问题描述
这几天一直在研究关于Socket的编程,因为之前完全没接触过,在网上查了很多关于这方面的资料,感觉雷同的很多,不知道为什么异步的时候还加个信号量处理,还有主要是目前需要同时连接两个服务器,客户端需要对不同的服务器传回的数据进行处理,如果采用异步的方法,有好几个回调方法,一个服务器还好,如果多出几个服务器,难道那些回调方法需要再重写一遍吗?而且异步的回调除了IAsyncResultar,又没法传递其他参数,而且也没有返回值,不知何解,可能主要是流程不太清楚把,网上都是前篇一律,不知道谁做过这方面比较稳定的程序,指导指导。
解决方案
解决方案二:
你先搞清楚一台服务器先,如果使用异步的话,实际上加一个循环就可以了,GetAddress函数就是包含多个服务器地址了,在ReceiveMessage函数中解析处理的你过来的数据,参考代码:///<summary>///开始建立通讯///</summary>publicstaticvoidStart(){foreach(variteminGetAddress()){//创建一个Socketvarsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{//连接到指定服务器的指定端口socket.Connect(item.IP,item.Port);if(socket.Connected){Console.WriteLine("{0}:{1}:Conneted....",item.IP,item.Port);Console.WriteLine("waitingfordebug_softwareconnecting...");//实现接受消息的方法socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}}catch(Exceptionex){Console.WriteLine(ex.Message);}}Console.Read();}///<summary>///异步接收数据///</summary>///<paramname="ar"></param>publicstaticvoidReceiveMessage(IAsyncResultar){try{varsocket=ar.AsyncStateasSocket;varlength=socket.EndReceive(ar);//分多次接收byte[]reallData=newbyte[length];Array.Copy(buffer,reallData,reallData.Length);stringdata=BitConverter.ToString(reallData);//递归接收socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}catch(Exceptionex){//如果有连接断开或者数据异常的雷达,开始启用重启模式,重新连接Console.WriteLine(ex.Message);}}
解决方案三:
引用1楼SomethingJack的回复:
你先搞清楚一台服务器先,如果使用异步的话,实际上加一个循环就可以了,GetAddress函数就是包含多个服务器地址了,在ReceiveMessage函数中解析处理的你过来的数据,参考代码:[code=csharp]///<summary>///开始建立通讯///</summary>publicstaticvoidStart(){foreach(variteminGetAddress()){//创建一个Socketvarsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{//连接到指定服务器的指定端口socket.Connect(item.IP,item.Port);if(socket.Connected){Console.WriteLine("{0}:{1}:Conneted....",item.IP,item.Port);Console.WriteLine("waitingfordebug_softwareconnecting...");//实现接受消息的方法socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}}catch(Exceptionex){Console.WriteLine(ex.Message);}}Console.Read();}///<summary>///异步接收数据///</summary>///<paramname="ar"></param>publicstaticvoidReceiveMessage(IAsyncResultar){try{varsocket=ar.AsyncStateasSocket;varlength=socket.EndReceive(ar);//分多次接收byte[]reallData=newbyte[length];Array.Copy(buffer,reallData,reallData.Length);stringdata=BitConverter.ToString(reallData);//递归接收socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}catch(Exceptionex){//如果有连接断开或者数据异常的雷达,开始启用重启模式,重新连接Console.WriteLine(ex.Message);}}
我做的这个是一个Winform程序,需要button来响应分别连接两个不同服务器,目前Client.cs参照网上的方法是这样写的usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}
[/code]但这个如果是多个服务器该怎么改呢
解决方案四:
[/code]usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}
解决方案五:
怎么格式一直都发不好呢usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}