zoukankan      html  css  js  c++  java
  • (转)C# Socket异步通信

    本文转载自:http://www.cnblogs.com/llllll/archive/2009/05/13/1455703.html

    服务器端

    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(" Press 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("") > -1)
                {
                    //所有数据读取完毕.
                    Console.WriteLine("Read {0} bytes from socket.   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(" Press 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("") > -1)
                {
                    // All the data has been read from the 
                    // client. Display it on the console.
                    Console.WriteLine("Read {0} bytes from socket.   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;
        }
    }
  • 相关阅读:
    Jvm性能监控和常用工具
    JVM内存分配和回收策略
    从ExtensionLoader理解Dubbo扩展机制
    类的加载和双亲委派模型
    截器和过滤器的区别
    Struts2的工作原理
    Action
    StrutsPrepareAndExecuteFilter
    单例模式
    Web工作原理
  • 原文地址:https://www.cnblogs.com/wpcnblog/p/3909701.html
Copyright © 2011-2022 走看看