处理多个客户端的c#套接字
我有下面的代码,我想实现为我的服务器。据我所知,它是异步的。并且应该允许来自多个客户端的连接处理多个客户端的c#套接字,c#,sockets,tcp,C#,Sockets,Tcp,我有下面的代码,我想实现为我的服务器。据我所知,它是异步的。并且应该允许来自多个客户端的连接 public void Start() { TcpListener listener = new TcpListener(IPAddress.Any, 10250); listener.Start(); Console.WriteLine("Listening..."); while (true) { IAsyncResult
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个简单的测试字符串请求。对于每个请求,它都会打开一个套接字,将数据发送到我的服务器,然后再次关闭套接字
这在运行一个测试应用程序时效果很好。但是,如果我打开两个测试应用程序,第二个无法连接到服务器。我想是因为我在异步处理请求。因为我的测试应用程序在每次调用之前打开然后关闭套接字,所以我可以处理来自多个客户端的请求。您这样做的方式,与使用
AcceptCpcClient
相比没有任何好处。只需循环并为每个接受的连接创建一个新线程:
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();
}
编辑
如果使用>=.Net4.5,最好使用新的网络方法,然后允许采用async
和wait
。因此,最好以我在中提供的示例作为起点
原职
下面的代码演示了如何异步接受多个客户机,而不必为每个连接分离一个新线程
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
}
您可以在大多数异步操作中使用此模式。我有一些示例代码,完全符合您的要求,但它在我的笔记本电脑上。如果我记得的话,如果有人还没有给你回信,我今晚就发。很抱歉延迟。那太好了,谢谢。StartAccept()中是否需要有一个循环来保存应用程序。在连接到达之前一直处于活动状态?我假设这是一个控制台应用程序。我建议从应用程序的主方法调用Start,然后用Console.ReadKey或类似的方法阻止程序关闭。这似乎是迄今为止给我最好结果的代码。@spender我喜欢这段代码,因为它简单。但是在
//继续之后
可以使用代码示例帮助管理多个客户端。ie将消息唯一地发送给每个客户端。@Cesar是,否则服务器将只接受一个客户端。我建议不要在.Net 4.5中使用此类代码,并鼓励您采用允许您使用async/await
的新网络方法。请看我的回答: