我正在使用 C# 开发一个基本的套接字服务器,它需要作为 Windows 窗体应用程序的一部分运行。我从MSDN的异步套接字服务器代码开始。像许多套接字服务器代码示例一样,这是一个控制台模式应用程序。下面是从 Main() 调用的 StartListening() 方法的示例:
public static void StartListening()
{
// data buffer for incoming data
byte[] bytes = new byte[1024];
IPAddress ipAddress = IPAddress.Parse(serverIpAddress);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, portNumber);
// create TCP/IP socket
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// bind socket to the local endpoint and listen for incoming connections
try
{
serverSocket.Bind(localEndPoint);
serverSocket.Listen(100);
while (true)
{
// set the allDone ManualResetEvent to nonsignaled state
allDone.Reset();
// start an asynchronous socket to listen for connections
Console.WriteLine("Waiting for a connection...");
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), serverSocket);
// wait until a connection is made before continuing
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
如您所见,其中有一个 while(true) 循环,它使用 ManualResetEvent 等待客户端连接建立,然后再进入 while 循环的下一次迭代。我不确定他们为什么包含该Console.WriteLine(\n"Press ENTER to continue...")
语句,因为无法摆脱 while(true) 循环。
无论如何,在考虑将其转换为 WinForms 应用程序时,我显然需要在另一个线程上运行服务器,但是当用户关闭我的应用程序时,我想确保套接字服务器“正确”关闭。我对这意味着什么的最佳猜测是关闭任何打开的客户端连接,打破侦听循环,然后关闭服务器套接字(不一定按此顺序)。
我已经看到一些建议,建议只将服务器线程设置为后台线程,并在应用程序关闭时让它被销毁,但这似乎不是很“干净”。例如,如果一个客户端在应用程序关闭时连接并发送数据,这对客户端有什么影响?任何人都可以提出关于正确关闭套接字服务器的“最佳实践”吗?