详解C# Socket异步通信实例
程序员文章站
2022-07-02 22:03:32
tcpserver
1、使用的通讯通道:socket
2、用到的基本功能:
①bind,
②listen,
③beginaccept
④endacc...
tcpserver
1、使用的通讯通道:socket
2、用到的基本功能:
①bind,
②listen,
③beginaccept
④endaccept
⑤beginreceive
⑥endreceive
3、函数参数说明
socket listener = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);
新建socket所使用的参数均为系统预定义的量,直接选取使用。
listener.bind(localendpoint);
localendpoint 表示一个定义完整的终端,包括ip和端口信息。
//new ipendpoint(ipaddress,port) //ipadress.parse("192.168.1.3") listener.listen(100);
监听
listener.beginaccept( new asynccallback(acceptcallback), listener);
asynccallback(acceptcallback),一旦连接上后的回调函数为acceptcallback。当系统调用这个函数时,自动赋予的输入参数为iasyncresoult类型变量ar。
listener,连接行为的容器。
socket handler = listener.endaccept(ar);
完成连接,返回此时的socket通道。
handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0, new asynccallback(readcallback), state);
接收的字节,0,字节长度,0,接收时调用的回调函数,接收行为的容器。
========
容器的结构类型为:
public class stateobject { // client socket. public socket worksocket = null; // size of receive buffer. public const int buffersize = 1024; // receive buffer. public byte[] buffer = new byte[buffersize]; // received data string. public stringbuilder sb = new stringbuilder(); }
容器至少为一个socket类型。
===============
// read data from the client socket. int bytesread = handler.endreceive(ar);
完成一次连接。数据存储在state.buffer里,bytesread为读取的长度。
handler.beginsend(bytedata, 0, bytedata.length, 0, new asynccallback(sendcallback), handler);
发送数据bytedata,回调函数sendcallback。容器handler
int bytessent = handler.endsend(ar);
发送完毕,bytessent发送字节数。
4 程序结构
主程序:
byte[] bytes = new byte[1024]; ipaddress ipaddress = ipaddress.parse("192.168.1.104"); ipendpoint localendpoint = new ipendpoint(ipaddress, 11000); // 生成一个tcp的socket socket listener = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); listener.bind(localendpoint); listener.listen(100); while (true) { // set the event to nonsignaled state. alldone.reset(); //开启异步监听socket console.writeline("waiting for a connection"); listener.beginaccept( new asynccallback(acceptcallback), listener); // 让程序等待,直到连接任务完成。在acceptcallback里的适当位置放置alldone.set()语句. alldone.waitone(); } console.writeline("\npress enter to continue"); console.read();
连接行为回调函数acceptcallback:
public static void acceptcallback(iasyncresult ar) { //添加此命令,让主线程继续. alldone.set(); // 获取客户请求的socket socket listener = (socket)ar.asyncstate; socket handler = listener.endaccept(ar); // 造一个容器,并用于接收命令. stateobject state = new stateobject(); state.worksocket = handler; handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0, new asynccallback(readcallback), state); }
读取行为的回调函数readcallback:
public static void readcallback(iasyncresult ar) { string content = string.empty; // 从异步state对象中获取state和socket对象. stateobject state = (stateobject)ar.asyncstate; socket handler = state.worksocket; // 从客户socket读取数据. int bytesread = 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} bytes from socket. \n data : {1}", content.length, content); // 给客户端响应. send(handler, content); } else { // 接收未完成,继续接收. handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0, new asynccallback(readcallback), state); } } }
发送消息给客户端:
private static void send(socket handler, string data) { // 消息格式转换. byte[] bytedata = encoding.ascii.getbytes(data); // 开始发送数据给远程目标. handler.beginsend(bytedata, 0, bytedata.length, 0, new asynccallback(sendcallback), handler); } private static void sendcallback(iasyncresult ar) { // 从state对象获取socket. socket handler = (socket)ar.asyncstate; //完成数据发送 int bytessent = handler.endsend(ar); console.writeline("sent {0} bytes to client.", bytessent); handler.shutdown(socketshutdown.both); handler.close(); }
在各种行为的回调函数中,所对应的socket都从输入参数的asyncstate属性获得。使用(socket)或者(stateobject)进行强制转换。beginreceive函数使用的容器为state,因为它需要存放传送的数据。
而其余接收或发送函数的容器为socket也可。
完整代码
using system; using system.net; using system.net.sockets; using system.text; using system.threading; // state object for reading client data asynchronously public class stateobject { // client socket. public socket worksocket = null; // size of receive buffer. public const int buffersize = ; // receive buffer. public byte[] buffer = new byte[buffersize]; // received data string. public stringbuilder sb = new stringbuilder(); } public class asynchronoussocketlistener { // thread signal. public static manualresetevent alldone = new manualresetevent(false); public asynchronoussocketlistener() { } public static void startlistening() { // data buffer for incoming data. byte[] bytes = new byte[]; // establish the local endpoint for the socket. // the dns name of the computer // running the listener is "host.contoso.com". //iphostentry iphostinfo = dns.resolve(dns.gethostname()); ipaddress ipaddress = ipaddress.parse("..."); ipendpoint localendpoint = new ipendpoint(ipaddress, ); // create a tcp/ip socket. socket listener = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); // bind the socket to the local endpoint and listen for incoming connections. try { listener.bind(localendpoint); listener.listen(); while (true) { // set the event to nonsignaled state. alldone.reset(); // start an asynchronous socket to listen for connections. console.writeline("waiting for a connection"); listener.beginaccept( new asynccallback(acceptcallback), listener); // wait until a connection is made before continuing. alldone.waitone(); } } catch (exception e) { console.writeline(e.tostring()); } console.writeline("\npress enter to continue"); console.read(); } public static void acceptcallback(iasyncresult ar) { // signal the main thread to continue. alldone.set(); // get the socket that handles the client request. socket listener = (socket)ar.asyncstate; socket handler = listener.endaccept(ar); // create the state object. stateobject state = new stateobject(); state.worksocket = handler; handler.beginreceive(state.buffer, , stateobject.buffersize, , new asynccallback(readcallback), state); } public static void readcallback(iasyncresult ar) { string content = string.empty; // retrieve the state object and the handler socket // from the asynchronous state object. stateobject state = (stateobject)ar.asyncstate; socket handler = state.worksocket; // read data from the client socket. int bytesread = handler.endreceive(ar); if (bytesread > ) { // there might be more data, so store the data received so far. state.sb.append(encoding.ascii.getstring( state.buffer, , bytesread)); // check for end-of-file tag. if it is not there, read // more data. content = state.sb.tostring(); if (content.indexof("<eof>") > -) { // all the data has been read from the // client. display it on the console. console.writeline("read {} bytes from socket. \n data : {}",content.length, content); // echo the data back to the client. send(handler, content); } else { // not all data received. get more. handler.beginreceive(state.buffer, , stateobject.buffersize, , new asynccallback(readcallback), state); } } } private static void send(socket handler, string data) { // convert the string data to byte data using ascii encoding. byte[] bytedata = encoding.ascii.getbytes(data); // begin sending the data to the remote device. handler.beginsend(bytedata, , bytedata.length, , new asynccallback(sendcallback), handler); } private static void sendcallback(iasyncresult ar) { try { // retrieve the socket from the state object. socket handler = (socket)ar.asyncstate; // complete sending the data to the remote device. int bytessent = handler.endsend(ar); console.writeline("sent {} bytes to client.", bytessent); handler.shutdown(socketshutdown.both); handler.close(); } catch (exception e) { console.writeline(e.tostring()); } } public static int main(string[] args) { startlistening(); return ; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。