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个简单的测试字符串请求。对于这些请求,它打开一个套接字,将数据发送到我的服务器,然后再次关闭套接字。
这在一个测试应用程序运行时工作良好。然而,如果我打开两个测试应用程序,第二个不能连接到服务器。我想,因为我正在处理异步请求。并且因为我的测试应用程序打开然后在每次调用之前关闭套接字,我可以处理来自多个客户端的请求?
编辑
如果使用>=. net 4.5,最好使用新的网络方法,然后允许采用async
和await
。因此,按照我在这篇文章中提供的例子作为起点可能会更好。
原始文章
下面的代码演示了如何异步地接受多个客户端,而不必为每个连接触发一个新线程。
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();
}