我们在生产中有一个应用程序应该是一个多线程套接字监听器。我开始怀疑,因为应用程序生成的日志使得它看起来好像正在处理它同步接收的流。为了努力不在这里粘贴代码墙,我将提供所谓的异步tcp代码的第一部分:这是正确的做法吗?
/// <summary>
/// Start an Asynchronous Socket to listen for connections.
/// </summary>
public static void StartListening()
{
Socket listenerSocket = null;
try
{
var ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[Socket.OSSupportsIPv6 ? 1 : 0];
//Create TCP/IP Socket
listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
listenerSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, 1);
//Bind the socket to the local endpoint and listen for incoming connections.
//listenerSocket.Bind(new IPEndPoint(ipAddress, m_client.RemotePort));
listenerSocket.Bind(new IPEndPoint(ipAddress, Int32.Parse(ConfigurationManager.AppSettings["ListenerPort"])));
listenerSocket.Listen(m_maxSocketConnections);
while (true)
{
//Set the event to nonsignaled state
m_pAllDone.Reset();
//Start an asynchronous socket
listenerSocket.BeginAccept(new AsyncCallback(AcceptCallback), listenerSocket);
//Wait until a connection is made and processed before continuing
m_pAllDone.WaitOne();
}
}
答案 0 :(得分:1)
这个调用不是多线程的,它只是异步的。来自the docs:
When your application calls BeginAccept, the system usually uses a separate thread to execute the specified callback method and blocks on EndAccept until a pending connection is retrieved.
BeginAccept方法创建另一个异步阻塞和处理传入数据包的线程。每次收到消息时,它都不会生成一个新线程。
答案 1 :(得分:0)
Socket.BeginAccept
是documented,因为“开始接受传入连接尝试的异步操作。”所以这部分操作(接受套接字连接请求)是异步的。这并不是说你在AcceptCallback
中所做的事情保证是多线程的 - 即使使用异步套接字,你也可以通过多种方式实现同步甚至单线程。