求助:关于异步多线程Socket已连接的客户端IP地址和端口

问题描述

如题,网上找了1个异步多线程的C#代码。可以实现客户端连接后客户端发送的数据再发送回去。但是我不知道怎么能把连接到这个服务器的客户端的IP显示出来,断开时候也有个提示,此外,比如说这个客户端连接了4个客户端,我想对第2个客户端主动发送数据怎么弄?求助usingSystem;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;//StateobjectforreadingclientdataasynchronouslypublicclassStateObject{//Clientsocket.publicSocketworkSocket=null;//Sizeofreceivebuffer.publicconstintBufferSize=1024;//Receivebuffer.publicbyte[]buffer=newbyte[BufferSize];//Receiveddatastring.publicStringBuildersb=newStringBuilder();}publicclassAsynchronousSocketListener{//Threadsignal.publicstaticManualResetEventallDone=newManualResetEvent(false);publicAsynchronousSocketListener(){}publicstaticvoidStartListening(){//Databufferforincomingdata.byte[]bytes=newByte[1024];//Establishthelocalendpointforthesocket.//TheDNSnameofthecomputer//runningthelisteneris"host.contoso.com".//IPHostEntryipHostInfo=Dns.Resolve(Dns.GetHostName());//IPAddressipAddress=ipHostInfo.AddressList[0];IPAddressipAddress=IPAddress.Parse("127.0.0.1");IPEndPointlocalEndPoint=newIPEndPoint(ipAddress,11000);//CreateaTCP/IPsocket.Socketlistener=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//Bindthesockettothelocal//endpointandlistenforincomingconnections.try{listener.Bind(localEndPoint);listener.Listen(100);while(true){//Settheeventtononsignaledstate.allDone.Reset();//Startanasynchronoussockettolistenforconnections.Console.WriteLine("Waitingforaconnection...");listener.BeginAccept(newAsyncCallback(AcceptCallback),listener);//Waituntilaconnectionismadebeforecontinuing.allDone.WaitOne();}}catch(Exceptione){Console.WriteLine(e.ToString());}Console.WriteLine("nPressENTERtocontinue...");Console.Read();}publicstaticvoidAcceptCallback(IAsyncResultar){//Signalthemainthreadtocontinue.allDone.Set();//Getthesocketthathandlestheclientrequest.Socketlistener=(Socket)ar.AsyncState;Sockethandler=listener.EndAccept(ar);//Createthestateobject.StateObjectstate=newStateObject();state.workSocket=handler;handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,newAsyncCallback(ReadCallback),state);}publicstaticvoidReadCallback(IAsyncResultar){Stringcontent=String.Empty;//Retrievethestateobjectandthehandlersocket//fromtheasynchronousstateobject.StateObjectstate=(StateObject)ar.AsyncState;Sockethandler=state.workSocket;//Readdatafromtheclientsocket.intbytesRead=handler.EndReceive(ar);if(bytesRead>0){//Theremightbemoredata,sostorethedatareceivedsofar.state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));//Checkforend-of-filetag.Ifitisnotthere,read//moredata.content=state.sb.ToString();if(content.IndexOf("<EOF>")>-1){//Allthedatahasbeenreadfromthe//client.Displayitontheconsole.Console.WriteLine("Read{0}bytesfromsocket.nData:{1}",content.Length,content);//Echothedatabacktotheclient.Send(handler,content);}else{//Notalldatareceived.Getmore.handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,newAsyncCallback(ReadCallback),state);}}}privatestaticvoidSend(Sockethandler,Stringdata){//ConvertthestringdatatobytedatausingASCIIencoding.byte[]byteData=Encoding.ASCII.GetBytes(data);//Beginsendingthedatatotheremotedevice.handler.BeginSend(byteData,0,byteData.Length,0,newAsyncCallback(SendCallback),handler);}privatestaticvoidSendCallback(IAsyncResultar){try{//Retrievethesocketfromthestateobject.Sockethandler=(Socket)ar.AsyncState;//Completesendingthedatatotheremotedevice.intbytesSent=handler.EndSend(ar);Console.WriteLine("Sent{0}bytestoclient.",bytesSent);handler.Shutdown(SocketShutdown.Both);handler.Close();}catch(Exceptione){Console.WriteLine(e.ToString());}}publicstaticintMain(String[]args){StartListening();return0;}}

解决方案

解决方案二:
用队列管理你的客户端连接,想怎么操作哪个客户端都行客户端IP可以通过客户端连接上来的socket.RemoteEndPoint获得
解决方案三:
socket.RemoteEndPoint这个就可以获取你远程客户端的IP等信息你可以在你接受客户连接的方法里面获取到客户端的IP同时你在这个方法里面把每个连接的客户端信息缓存起来这样你之后想给哪个客户端发送消息都可以了啊你可以以客户端IP地址作为键,客户端连接信息作为值进行缓存。
解决方案四:
引用2楼huangcailian的回复:

socket.RemoteEndPoint这个就可以获取你远程客户端的IP等信息你可以在你接受客户连接的方法里面获取到客户端的IP同时你在这个方法里面把每个连接的客户端信息缓存起来这样你之后想给哪个客户端发送消息都可以了啊你可以以客户端IP地址作为键,客户端连接信息作为值进行缓存。

可以按照上面那个给我写个简单的怎么缓冲客户端信息代码么?我是新手,不知道怎么写。
解决方案五:
引用1楼chuheiqian的回复:

用队列管理你的客户端连接,想怎么操作哪个客户端都行客户端IP可以通过客户端连接上来的socket.RemoteEndPoint获得

怎么缓冲发送呢?额,我只在网上搜到了如何打印出来,Console.WriteLine("connected:"+IPAddress.Parse(((IPEndPoint)handler.RemoteEndPoint).Address.ToString())+"port:"+((IPEndPoint)handler.RemoteEndPoint).Port.ToString());

解决方案六:
把连接上的客户端socket存到一个集合中,然后弄个列表把集合显示出来选那个客户端就向谁发消息呗不知道你要的是不是这样的功能,,
解决方案七:
这里有一大堆问题。随便说几个:1.服务器端不要写"127.0.0.1",要监听IPAddress.Any。2.服务器端尽量不要写Listen(100)。你可以写Listen(int.MaxValue),或者一个大于10000的数字。3.如果要写allDone.Set()语句,那么应该放到Sockethandler=listener.EndAccept(ar)语句后边。4.不要在intbytesRead=handler.EndReceive(ar)语句之后去把最近读到的一个数据包的内容当作一条消息。因为tcp为了保证通讯的“君子协定”,具有“沾包、分包”的特性。一次收到的内容,可能只有消息的一部分(而不是全部),也可能包括不止一个消息的内容。你的程序在这里的问题太严重了,这是一个极其严重的bug!关于你提的问题。在你得到所谓handler的时候,可以把它保存到你的AsynchronousSocketListener类声明的一个staticList<Socket>

的集合中(这并不是队列)。最后要说明的是,在.net中的Socket只是为了兼容linux风格的代码而已,它效率低,没有直接封装IOCP机制。在.net中,你应该使用TcpListener/TcpClient,而不是Socket类型!在windows下,不使用更高级IOCP机制而去使用普通的通用其它平台的Socket类,就显得“弱”了。
解决方案八:
通常,会自己封装一个Session类,而不是仅仅保持Socket集合。例如publicclassSession{publicstring授权唯一id;publicTcpClientClient;publicstring登录用户id;publicDateTime最后心跳时间;..........}publicclassAsynchronousSocketListener{staticList<Session>Clients=newList<Session>();........

解决方案九:
引用7楼sp1234的回复:

通常,会自己封装一个Session类,而不是仅仅保持Socket集合。例如publicclassSession{publicstring授权唯一id;publicTcpClientClient;publicstring登录用户id;publicDateTime最后心跳时间;..........}publicclassAsynchronousSocketListener{staticList<Session>Clients=newList<Session>();........

谢谢你了,我再去学习下,是C#新手,之前没弄过这个~

时间: 2024-09-24 00:16:13

求助:关于异步多线程Socket已连接的客户端IP地址和端口的相关文章

C# Socket编程如何获取连接的远程客户端的IP地址和端口

问题描述 最近做C#Socket编程时遇到了一个非常奇怪的问题,我在A市,用了一个第三方做端口映射的软件成功实现了跨局域网进行TCP通信的问题,也就是我的办公室的电脑作为服务器,我的内网IP为172.23.21.168,端口号为51888,并用第三方软件做了端口映射,将端口映射为31669,将客户端程序发给我一个在另一个城市B市的朋友(他也处在办公室的网络中)帮我测试,他用客户端程序已经成功连接到了我的服务器,并可以成功跟我进行通信(打字聊天信息双方都能接收和发送).现在问题来了,我用C#里的s

C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨_C#教程

1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用.http协议在应用层运行. 02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证. 03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP.IGMP.RIP.OSPF.IP(v4,v6)等. 04,链路层(Link):又称为物

1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

 1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端口号"就称为socket. 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就唯一标识一个连接.socket本身有"插座"的意思,因此用来描述网络连 接的一对一关系. TCP/IP协议最早在BSD UNIX上实现,

客户端与服务器-C#客户端为什么连接不上服务器,当ip地址为127.0.0.1是没有问题的

问题描述 C#客户端为什么连接不上服务器,当ip地址为127.0.0.1是没有问题的 就是自己的电脑是连接路由器的,但是ip不是192.168.开头的,不知道是公网问题还是什么问题,测试都是用自己的一台电脑的. 解决方案 服务端Server using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using Syste

socket #-C#SOCKET长连接小数据程序未响应

问题描述 C#SOCKET长连接小数据程序未响应 最近由于业务的需要,Linux系统嵌入式设备往我做的服务程序发送数据. 速度奇慢,而且还是程序无响应.后来自己用C#写了一个客户端用来测试.已经用了线程池,不知道用法对不对.请大家帮忙看下. 服务端: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.N

服务器socket接受多个客户端的连接以及接收数据的问题

问题描述 我现在的问题是,我服务器是C#写的socket监听,现在有多个客户端连接上来,服务器接受数据接收不到,(前面几次接收是正常的)代码如下:(1)服务器端publicstaticvoidsocketListener(){//服务器IP地址IPAddressip=IPAddress.Parse("10.0.1.81");//IPAddressip=IPAddress.Parse("10.0.1.80");SocketserverSocket=newSocket(

Socket编程 (连接,发送消息) (Tcp、Udp) - Part1

原文 http://www.cnblogs.com/zengqinglei/archive/2013/04/27/3046119.html Socket编程 (连接,发送消息) (Tcp.Udp)  本篇文章主要实现Socket在Tcp\Udp协议下相互通讯的方式.(服务器端与客户端的通讯) 1.基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息. 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定服

Java Web项目中使用Socket通信多线程、长连接的方法_java

很多时候在javaweb项目中我们需要用到Socket通信来实现功能,在web中使用Socket我们需要建立一个监听程序,在程序启动时,启动socket监听.我们的应用场景是在java项目中,需要外接如一个硬件设备,通过tcp通信,获取设备传上来的数据,并对数据做回应. 先看一下web的监听代码: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class

CentOS下PureFtp出现“数据 Socket 错误 连接已超时”错误解决办法

前段时间配置了PureFTP上传程序,但期间出现种种让人不爽的问题!比如在本地使用 FlashFTP 时出现最多的"数据 Socket 错误 连接已超时"错误,无论使用主动还是被动模式上传,都会有类似错误! [右] 数据 Socket 错误: 没有到主机的通道 [右] 列表 错误 [右] PASV [右] 227 Entering Passive Mode (116,255,246,176,83,197) [右] 正在打开数据连接 IP: 116.255.246.176 端口: 214