c#套接字处理多个客户端

本文关键字:客户端 字处理 | 更新日期: 2023-09-27 17:50:40

我有下面的代码,我想实现作为我的服务器。据我所知,它是异步的。并且应该允许来自多个客户端的连接…

public void Start()
{          
    TcpListener listener = new TcpListener(IPAddress.Any, 10250);
    listener.Start();
    Console.WriteLine("Listening...");
    while (true)
    {
        IAsyncResult res = listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
        connectionWaitHandle.WaitOne();
    }
}
private void HandleAsyncConnection(IAsyncResult res)
{
    TcpListener listener = (TcpListener)res.AsyncState;
    TcpClient client = listener.EndAcceptTcpClient(res);
    connectionWaitHandle.Set();
    StringBuilder sb = new StringBuilder();
    var data = new byte[client.ReceiveBufferSize];
    using (NetworkStream ns = client.GetStream())
    {             
        // Test reply
        Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString());
        ns.Write(replyData, 0, replyData.Length);
        ns.Flush();
        ns.Close();
    }
    client.Close();
}

我有一个测试应用程序,它只是向我的服务器发出请求。正如您在代码中看到的,服务器只回复它的日期/时间。测试应用程序发送20个简单的测试字符串请求。对于这些请求,它打开一个套接字,将数据发送到我的服务器,然后再次关闭套接字。

这在一个测试应用程序运行时工作良好。然而,如果我打开两个测试应用程序,第二个不能连接到服务器。我想,因为我正在处理异步请求。并且因为我的测试应用程序打开然后在每次调用之前关闭套接字,我可以处理来自多个客户端的请求?

c#套接字处理多个客户端

编辑

如果使用>=. net 4.5,最好使用新的网络方法,然后允许采用asyncawait。因此,按照我在这篇文章中提供的例子作为起点可能会更好。

原始文章

下面的代码演示了如何异步地接受多个客户端,而不必为每个连接触发一个新线程。

private TcpListener listener;
public void Start()
{          
    listener = new TcpListener(IPAddress.Any, 10250);
    listener.Start();
    Console.WriteLine("Listening...");
    StartAccept();
}
private void StartAccept()
{
    listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
}
private void HandleAsyncConnection(IAsyncResult res)
{
    StartAccept(); //listen for new connections again
    TcpClient client = listener.EndAcceptTcpClient(res);
    //proceed
}

您这样做,与使用AcceptTcpClient相比没有任何好处。只需为每个接受的连接循环并创建一个新线程:

public void Start()
{          
    TcpListener listener = new TcpListener(IPAddress.Any, 10250);
    listener.Start();
    Console.WriteLine("Listening...");
    while (canRun)
    {
       var client = listener.AcceptTcpClient();
       new Thread(ClientThread).Start(client);
    }
}
private void ClientThread(IAsyncResult res)
{
    TcpClient client = (TcpClient)res.AsyncState;
    StringBuilder sb = new StringBuilder();
    var data = new byte[client.ReceiveBufferSize];
    using (NetworkStream ns = client.GetStream())
    {             
        // Test reply
        Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString());
        ns.Write(replyData, 0, replyData.Length);
        ns.Flush();
        ns.Close();
    }
    client.Close();
}
使用异步方法的黄金法则是不要阻塞操作。阻塞会破坏使用异步操作的目的。
public void Start()
{          
    TcpListener listener = new TcpListener(IPAddress.Any, 10250);
    listener.Start();
    Console.WriteLine("Listening...");
    listener.BeginAcceptTcpClient(OnAccept, listener);
}
private void OnAccept(IAsyncResult res)
{
    TcpListener listener = (TcpListener)res.AsyncState;
    TcpClient client = listener.EndAcceptTcpClient(res);
    StringBuilder sb = new StringBuilder();
    var data = new byte[client.ReceiveBufferSize];
    using (NetworkStream ns = client.GetStream())
    {             
        // Test reply
        Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString());
        ns.Write(replyData, 0, replyData.Length);
        ns.Flush();
        ns.Close();
    }
    client.Close();
}