zoukankan      html  css  js  c++  java
  • [转载]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 = 1024;
        
    // 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[1024];

            
    // 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("192.168.1.104");
            IPEndPoint localEndPoint 
    = new IPEndPoint(ipAddress, 11000);

            
    // 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(
    100);

                
    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, 
    0, StateObject.BufferSize, 0,
                
    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 > 0)
            
    {
                
    // There  might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(
                    state.buffer, 
    0, bytesRead));

                
    // Check for end-of-file tag. If it is not there, read 
                
    // more data.
                content = state.sb.ToString();
                
    if (content.IndexOf("<EOF>"> -1)
                
    {
                    
    // All the data has been read from the 
                    
    // client. Display it on the console.
                    Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                        content.Length, content);
                    
    // Echo the data back to the client.
                    Send(handler, content);
                }

                
    else
                
    {
                    
    // Not all data received. Get more.
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    
    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, 0, byteData.Length, 0,
                
    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 {0} 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 0;
        }

    }
     ------------------------
     

    主程序:


     public static int Main(String[] args)
        {


            IPAddress ipAddress 
    = IPAddress.Parse("192.168.1.104");
            
    int port = 20000;
            IPEndPoint remoteEP 
    = new IPEndPoint(ipAddress, port);

            
    // 生成一个TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            
    // 与目标终端连接.
            client.BeginConnect(remoteEP,
                
    new AsyncCallback(ConnectCallback), client);
            
    //等待,直到连接程序完成。在ConnectCallback中适当位置有connecDone.Set()语句
            connectDone.WaitOne();

            
    // 发送数据到远程终端.
            Send(client, "This is a test<EOF>");
            sendDone.WaitOne();

            
    // 接收返回数据.
            Receive(client);
            receiveDone.WaitOne();

            
    // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);

            
    // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();

            
    return 0;

        }

    连接部分Callback:


        private static void ConnectCallback(IAsyncResult ar)
        {

                
    // 从state对象获取socket.
                Socket client = (Socket)ar.AsyncState;

                
    // 完成连接.
                client.EndConnect(ar);

                Console.WriteLine(
    "Socket connected to {0}",
                    client.RemoteEndPoint.ToString());

                
    // 连接已完成,主线程继续.
                connectDone.Set();
        }

    数据接收:


       private static void Receive(Socket client)
        {

                
    // 构造容器state.
                StateObject state = new StateObject();
                state.workSocket 
    = client;

                
    // 从远程目标接收数据.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    
    new AsyncCallback(ReceiveCallback), state);
      
        }

        
    private static void ReceiveCallback(IAsyncResult ar)
        {

                
    // 从输入参数异步state对象中获取state和socket对象
                StateObject state = (StateObject)ar.AsyncState;
                Socket client 
    = state.workSocket;

                
    //从远程设备读取数据
                int bytesRead = client.EndReceive(ar);

                
    if (bytesRead > 0)
                {
                    
    // 有数据,存储.
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    
    // 继续读取.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        
    new AsyncCallback(ReceiveCallback), state);
                }
                
    else
                {
                    
    // 所有数据读取完毕.
                    if (state.sb.Length > 1)
                    {
                        response 
    = state.sb.ToString();
                    }
                    
    // 所有数据读取完毕的指示信号.
                    receiveDone.Set();
                }

        }

    发送数据:



        
    private static void Send(Socket client, String data)
        {
            
    // 格式转换.
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            
    // 开始发送数据到远程设备.
            client.BeginSend(byteData, 0, byteData.Length, 0,
                
    new AsyncCallback(SendCallback), client);
        }

        
    private static void SendCallback(IAsyncResult ar)
        {

                
    // 从state对象中获取socket
                Socket client = (Socket)ar.AsyncState;

                
    // 完成数据发送.
                int bytesSent = client.EndSend(ar);
                Console.WriteLine(
    "Sent {0} bytes to server.", bytesSent);

                
    // 指示数据已经发送完成,主线程继续.
                sendDone.Set();

        }
  • 相关阅读:
    SharePoint开发中可能用到的各种Context(上下文)
    SharePoint 2013中的视频体验增强(1)——把大象装进冰箱
    SharePoint 2013之Office Web Apps Server(1)
    Office 2013 (Wave 15)来了
    SharePoint 2013新特性:图像呈现形式(Image Rendition)
    SharePoint 2013之Office Web Apps Server(2)
    在自己的代码中获取SharePoint的存储占用情况
    Showing Hyperlink Cues with CSS
    (翻译) 价目表:实例和最佳策略
    用CSS制作大背景网站,以及80个大背景图片网站。
  • 原文地址:https://www.cnblogs.com/fx2008/p/2249219.html
Copyright © 2011-2022 走看看