基于webapi的websocket聊天室(番外一)-手动管理连接看看?

由于websockt我们看不到客户端发起连接,服务端接收连接的过程,我自己用socket测试一下。
代码非常简单

  • 服务器监听端口
  • 等待客户端连接,然后维护到一个集合中
  • 每接到连接,就开启一个聊天线程
    static void Main(string[] args)
    {
        //服务器
        if (args.Length == 1) { 
            int serverPort = Convert.ToInt32(args[0]);
            var server = new TcpListener(IPAddress.Parse("127.0.0.1"),serverPort);
            Console.WriteLine($"TCP服务器  127.0.0.1:{serverPort}");
            server.Start();
            int cnt = 0;
            Task.Run(async() =>
            {
                List<TcpClient> clients= new List<TcpClient>();
                while (true)
                {
                    TcpClient client = await server.AcceptTcpClientAsync();
                    clients.Add(client);
                    cnt++;
                    var ep = client.Client.RemoteEndPoint as IPEndPoint;
                    Console.WriteLine($"TCP客户端_{cnt}  {ep.Address}:{ep.Port}");
                    //给这个客户端开一个聊天线程
                    //操作系统将会根据游客端口对应表将控制权交给对应游客线程
                    StartChat(client);
                }
            }).Wait();
        }
        //客户端
        else if (args.Length == 3)
        {
            int clientPort = Convert.ToInt32(args[0]);
            int serverPort = Convert.ToInt32(args[1]);
            string msg = args[2];
            var client=new TcpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), clientPort));
            Console.WriteLine($"TCP客户端  127.0.0.1:{clientPort}");
            Task.Run(async () =>
            {
                await client.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), serverPort));
                Console.WriteLine($"连接到 127.0.0.1:{serverPort}");
                //打招呼
                var msgBytes=UTF8Encoding.UTF8.GetBytes(msg);
                await client.Client.SendAsync(msgBytes);
                //等待数据,阻塞在这里,保持连接
                await client.Client.ReceiveAsync(new ArraySegment<byte>(new byte[100]));
            }).Wait();
        }
    }

    public static async Task StartChat(TcpClient client)
    {
        var buffer = new byte[100];
        while (true)
        {
            //阻塞接收消息
            int msgLength = await client.Client.ReceiveAsync(new ArraySegment<byte>(buffer));
            string str=UTF8Encoding.UTF8.GetString(buffer,0,msgLength);
            Console.WriteLine(str);
        }
    }
}

我们测试建立一个服务端,和三个连接到这个服务端的客户端
虽然三个游客都向一个服务器端口5234发送消息,但操作系统根据端口连接对应表知道将消息发送给哪个线程。就好像在一个端口划分出来了3个信道。

  • 每个信道可以使用具体的http协议或我们写的RCP协议来序列化和反序列化
  • 要注意的是,这些不同的连接(TcpClient)是同一个TCPLisener对象到的。这就是在一个程序中使用多种通信协议。

image

上一篇: Chart.js (v2.9.4)概要介绍