当前位置: 移动技术网 > IT编程>开发语言>c# > 详解C# Socket异步通信实例

详解C# Socket异步通信实例

2019年07月18日  | 移动技术网IT编程  | 我要评论

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 ;
   }
 
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网