[英].NET TcpSocket programming
在.NET的多连接环境中接受套接字的正确方法是什么? 即使负载很高,以下条件是否足够?
while (true)
{
//block untill socket accepted
var socket = tcpListener.AcceptSocket();
DoStuff(socket) //e.g. spawn thread and read data
}
也就是说,我可以在单个线程中接受套接字,然后在线程/数据流/任何形式中处理套接字。 所以问题只是关于接受部分。
您可能需要BeginAccept异步操作,而不是同步Accept。
而且,如果您想处理高负载,则绝对不希望每个连接都有线程-同样,您可以使用异步方法。
这样做应该可以,但是如果负载更高,则可以考虑使用此方法的异步版本: BeginAcceptSocket / EndAcceptSocket 。
我认为最好的方法是调用BeginAccept(),然后在OnAccept内再次调用BeginAccept。这应该为您提供最佳的并发性。
OnAccept应该是这样的:
private void OnAccept(IAsyncResult ar)
{
bool beginAcceptCalled = false;
try
{
//start the listener again
_listener.BeginAcceptSocket(OnAccept, null);
beginAcceptCalled = true;
Socket socket = _listener.EndAcceptSocket(ar);
//do something with the socket..
}
catch (Exception ex)
{
if (!beginAcceptCalled)
{
//try listening to connections again
_listener.BeginAcceptSocket(OnAccept, null);
}
}
}
在性能方面,这并不重要。 重要的是您如何与每个客户沟通。 这种处理将比接受套接字消耗更多的CPU。
我会将BeginAccept
/ EndAccept
用于侦听器套接字, BeginReceive
/ EndReceive
用于客户端套接字。
由于我使用的是异步CTP和数据流,因此当前代码如下所示:
private async void WaitForSockets()
{
var socket = await tcpListener.AcceptSocketAsync();
WaitForSockets();
incomingSockets.Post(socket);
}
注意,看起来像递归调用不会导致堆栈溢出或阻塞。 它将只是为新的套接字启动一个新的等待者并退出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.