C#网络编程学习(4)---Socket Tcp进阶之 使用异步循环接收客户端连接和信息

1、方法介绍

BeginAccept(AsyncCallback callback, object state);
异步开始监听客户端连接。

  1. callback为一个委托,在成功接收客户端连接时调用委托方法。
  2. 向委托方法中传递的参数

**EndAccept (IAsyncResult result);** 结束监听客户端连接,一般在委托中成功接收连接后使用。 1. **result**:它存储此异步操作的状态信息以及任何用户定义数据。 返回。使用**result.AsyncState** 可以接收传递过来的参数。
**BeginReceive (byte[] buffer, int offset, int size, SocketFlags flag, AsyncCallback callback, object state);** 异步接收服务器发送来的数据 1. 存储接收的数据 2. 从buffer哪开始存储数据 3. 要接受最大的字节数 4. SocketFlags 值的按位组合 5. 接收成功后调用的委托方法 6. 要传递的参数

2、服务器端

namespace Tcp服务器端
{
    class Program
    {
        /// <summary>
        /// 接收客户端发送数据数组
        /// </summary>
        static byte[] data = new byte[1024];

        static void Main(string[] args)
        {
            StartServerAsync();
        }

        static void StartServerAsync()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
            serverSocket.Bind(point);
            serverSocket.Listen(100);

            //异步监听客户端连接
            serverSocket.BeginAccept(AcceptCallBack,serverSocket);

            Console.ReadKey();
        }
        /// <summary>
        /// 接收到客户端连接时调用
        /// </summary>
        static void AcceptCallBack(IAsyncResult ar)
        {
            Console.WriteLine("一个客户端连接了进来\n");
            Socket serverSocket = null;
            try
            {
                //接收传递过来的main中的serverSocket
                serverSocket = ar.AsyncState as Socket;
                //结束接收,返回接收到的clientSocket
                Socket clientSocket = serverSocket.EndAccept(ar);

                clientSocket.Send(Encoding.UTF8.GetBytes("你好呀。。。客户端"));
                //异步开始监听客户端传递数据
                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);  //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数(会被传递给回调函数)

                //继续处理下一个客户端的连接,相当于一个伪递归
                serverSocket.BeginAccept(AcceptCallBack, serverSocket);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                if (serverSocket != null)
                    serverSocket.Close();
            }
        }
        /// <summary>
        /// 接收到客户端发送的数据时调用
        /// </summary>
        static void ReceiveCallBack(IAsyncResult ar)
        {
            Socket clientSocket = null;
            try
            {
                clientSocket = ar.AsyncState as Socket;
                int count = clientSocket.EndReceive(ar);

                //正常关闭的情况
                if (count == 0)
                {
                    Console.WriteLine("一个客户端正常断开了连接");
                    clientSocket.Close();
                    return;
                }
                Console.WriteLine("接收到数据:" + Encoding.UTF8.GetString(data, 0, count));

                clientSocket.BeginReceive(data, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);  //从头开始存,最大数量,none,接收到客户端后执行的回调函数,要传递的参数
            }
            catch (Exception e)
            {
                //非正常关闭的情况
                Console.WriteLine(e);
                if (clientSocket != null)
                    clientSocket.Close();
            }
        }

        
    }
}

3、客户端

namespace Tcp客户端
{
    class Program
    {
        static void Main(string[] args)
        {
            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.1.3"), 5555);
            clientSocket.Connect(point);

            byte[] data = new byte[1024];
            int length = clientSocket.Receive(data);
            Console.WriteLine(Encoding.UTF8.GetString(data, 0, length));

            //循环向服务器发送数据
            while (true)
            {
                string s = Console.ReadLine();
                //输入c正常退出,直接按×异常退出
                if (s == "c")
                {
                    clientSocket.Close();
                    return;
                }
                clientSocket.Send(Encoding.UTF8.GetBytes(s));
            }
            

            Console.ReadKey();

        }
    }
}

4、效果

服务器可以接收多个客户端连接
多个客户端都可以向服务器发送数据

posted @ 2019-05-27 17:07  Fflyqaq  阅读(3102)  评论(1编辑  收藏  举报