好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解C# Socket异步通信实例

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测试数据".

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

   }

 

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://HdhCmsTestcnblogs测试数据/kingmoon/archive/2011/04/29/2032452.html

dy("nrwz");

查看更多关于详解C# Socket异步通信实例的详细内容...

  阅读:35次