详解C# Socket异步通信实例
TCPServer
1、使用的通讯通道:socket
2、用到的基本功能:
①Bind,
②Listen,
③BeginAccept
④EndAccept
⑤BeginReceive
⑥EndReceive
3、函数参数说明
Socketlistener=newSocket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);
新建socket所使用的参数均为系统预定义的量,直接选取使用。
listener.Bind(localEndPoint);
localEndPoint表示一个定义完整的终端,包括IP和端口信息。
//newIPEndPoint(IPAddress,port) //IPAdress.Parse("192.168.1.3") listener.Listen(100);
监听
listener.BeginAccept( newAsyncCallback(AcceptCallback), listener);
AsyncCallback(AcceptCallback),一旦连接上后的回调函数为AcceptCallback。当系统调用这个函数时,自动赋予的输入参数为IAsyncResoult类型变量ar。
listener,连接行为的容器。
Sockethandler=listener.EndAccept(ar);
完成连接,返回此时的socket通道。
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0, newAsyncCallback(ReadCallback),state);
接收的字节,0,字节长度,0,接收时调用的回调函数,接收行为的容器。
========
容器的结构类型为:
publicclassStateObject { //Clientsocket. publicSocketworkSocket=null; //Sizeofreceivebuffer. publicconstintBufferSize=1024; //Receivebuffer. publicbyte[]buffer=newbyte[BufferSize]; //Receiveddatastring. publicStringBuildersb=newStringBuilder(); }
容器至少为一个socket类型。
===============
//Readdatafromtheclientsocket. intbytesRead=handler.EndReceive(ar);
完成一次连接。数据存储在state.buffer里,bytesRead为读取的长度。
handler.BeginSend(byteData,0,byteData.Length,0, newAsyncCallback(SendCallback),handler);
发送数据byteData,回调函数SendCallback。容器handler
intbytesSent=handler.EndSend(ar);
发送完毕,bytesSent发送字节数。
4程序结构
主程序:
byte[]bytes=newByte[1024]; IPAddressipAddress=IPAddress.Parse("192.168.1.104"); IPEndPointlocalEndPoint=newIPEndPoint(ipAddress,11000); //生成一个TCP的socket Socketlistener=newSocket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp); listener.Bind(localEndPoint); listener.Listen(100); while(true) { //Settheeventtononsignaledstate. allDone.Reset(); //开启异步监听socket Console.WriteLine("Waitingforaconnection"); listener.BeginAccept( newAsyncCallback(AcceptCallback), listener); //让程序等待,直到连接任务完成。在AcceptCallback里的适当位置放置allDone.Set()语句. allDone.WaitOne(); } Console.WriteLine("\nPressENTERtocontinue"); Console.Read();
连接行为回调函数AcceptCallback:
publicstaticvoidAcceptCallback(IAsyncResultar) { //添加此命令,让主线程继续. allDone.Set(); //获取客户请求的socket Socketlistener=(Socket)ar.AsyncState; Sockethandler=listener.EndAccept(ar); //造一个容器,并用于接收命令. StateObjectstate=newStateObject(); state.workSocket=handler; handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0, newAsyncCallback(ReadCallback),state); }
读取行为的回调函数ReadCallback:
publicstaticvoidReadCallback(IAsyncResultar) { Stringcontent=String.Empty; //从异步state对象中获取state和socket对象. StateObjectstate=(StateObject)ar.AsyncState; Sockethandler=state.workSocket; //从客户socket读取数据. intbytesRead=handler.EndReceive(ar); if(bytesRead>0) { //如果接收到数据,则存起来 state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead)); //检查是否有结束标记,如果没有则继续读取 content=state.sb.ToString(); if(content.IndexOf("<EOF>")>-1) { //所有数据读取完毕. Console.WriteLine("Read{0}bytesfromsocket.\nData:{1}", content.Length,content); //给客户端响应. Send(handler,content); } else { //接收未完成,继续接收. handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0, newAsyncCallback(ReadCallback),state); } } }
发送消息给客户端:
privatestaticvoidSend(Sockethandler,Stringdata) { //消息格式转换. byte[]byteData=Encoding.ASCII.GetBytes(data); //开始发送数据给远程目标. handler.BeginSend(byteData,0,byteData.Length,0, newAsyncCallback(SendCallback),handler); } privatestaticvoidSendCallback(IAsyncResultar) { //从state对象获取socket. Sockethandler=(Socket)ar.AsyncState; //完成数据发送 intbytesSent=handler.EndSend(ar); Console.WriteLine("Sent{0}bytestoclient.",bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); }
在各种行为的回调函数中,所对应的socket都从输入参数的AsyncState属性获得。使用(Socket)或者(StateObject)进行强制转换。BeginReceive函数使用的容器为state,因为它需要存放传送的数据。
而其余接收或发送函数的容器为socket也可。
完整代码
usingSystem; usingSystem.Net; usingSystem.Net.Sockets; usingSystem.Text; usingSystem.Threading; //Stateobjectforreadingclientdataasynchronously publicclassStateObject { //Clientsocket. publicSocketworkSocket=null; //Sizeofreceivebuffer. publicconstintBufferSize=; //Receivebuffer. publicbyte[]buffer=newbyte[BufferSize]; //Receiveddatastring. publicStringBuildersb=newStringBuilder(); } publicclassAsynchronousSocketListener { //Threadsignal. publicstaticManualResetEventallDone=newManualResetEvent(false); publicAsynchronousSocketListener() { } publicstaticvoidStartListening() { //Databufferforincomingdata. byte[]bytes=newByte[]; //Establishthelocalendpointforthesocket. //TheDNSnameofthecomputer //runningthelisteneris"host.contoso.com". //IPHostEntryipHostInfo=Dns.Resolve(Dns.GetHostName()); IPAddressipAddress=IPAddress.Parse("..."); IPEndPointlocalEndPoint=newIPEndPoint(ipAddress,); //CreateaTCP/IPsocket. Socketlistener=newSocket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp); //Bindthesockettothelocalendpointandlistenforincomingconnections. try { listener.Bind(localEndPoint); listener.Listen(); 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,,StateObject.BufferSize,,newAsyncCallback(ReadCallback),state); } publicstaticvoidReadCallback(IAsyncResultar) { Stringcontent=String.Empty; //Retrievethestateobjectandthehandlersocket //fromtheasynchronousstateobject. StateObjectstate=(StateObject)ar.AsyncState; Sockethandler=state.workSocket; //Readdatafromtheclientsocket. intbytesRead=handler.EndReceive(ar); if(bytesRead>) { //Theremightbemoredata,sostorethedatareceivedsofar. state.sb.Append(Encoding.ASCII.GetString( state.buffer,,bytesRead)); //Checkforend-of-filetag.Ifitisnotthere,read //moredata. content=state.sb.ToString(); if(content.IndexOf("<EOF>")>-) { //Allthedatahasbeenreadfromthe //client.Displayitontheconsole. Console.WriteLine("Read{}bytesfromsocket.\nData:{}",content.Length,content); //Echothedatabacktotheclient. Send(handler,content); } else { //Notalldatareceived.Getmore. handler.BeginReceive(state.buffer,,StateObject.BufferSize,,newAsyncCallback(ReadCallback),state); } } } privatestaticvoidSend(Sockethandler,Stringdata) { //ConvertthestringdatatobytedatausingASCIIencoding. byte[]byteData=Encoding.ASCII.GetBytes(data); //Beginsendingthedatatotheremotedevice. handler.BeginSend(byteData,,byteData.Length,, newAsyncCallback(SendCallback),handler); } privatestaticvoidSendCallback(IAsyncResultar) { try { //Retrievethesocketfromthestateobject. Sockethandler=(Socket)ar.AsyncState; //Completesendingthedatatotheremotedevice. intbytesSent=handler.EndSend(ar); Console.WriteLine("Sent{}bytestoclient.",bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch(Exceptione) { Console.WriteLine(e.ToString()); } } publicstaticintMain(String[]args) { StartListening(); return; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。