我正在使用TCPListener类异步编写C#中的服务器。我目前有以下代码作为我的网络监听器类:
public class NetworkListener
{
private readonly SessionController _sessions;
private readonly TcpListener _server;
public NetworkListener(KernelConfiguration configuration, SessionController sessions)
{
_server = new TcpListener(new IPEndPoint(IPAddress.Any, configuration.Network.port));
_server.Start();
_sessions = sessions;
}
public async Task StartAccepting(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
var client = await _server.AcceptTcpClientAsync();
Console.WriteLine($"New connection from {client.Client.RemoteEndPoint}.");
_sessions.AddSession(client, Guid.NewGuid(), out var session);
await session.StartReceiving();
}
Console.WriteLine("stop");
}
public void Dispose()
{
_server.Stop();
}
}
作为我的program.cs,我有:
internal class Program
{
private static NetworkListener _networkListener;
private static CancellationTokenSource _cancellationTokenSource;
private static async Task Main(string[] args)
{
_networkListener = new NetworkListener(new KernelConfiguration(), new SessionController());
_cancellationTokenSource = new CancellationTokenSource();
var thread = new Thread(ProgressConsoleCommands);
thread.Start();
try
{
await _networkListener.StartAccepting(_cancellationTokenSource.Token);
}
finally
{
_networkListener.Dispose();
}
}
private static void ProgressConsoleCommands()
{
while (true)
{
var command = Console.ReadLine();
Console.WriteLine(command);
switch (command)
{
case "close":
Console.WriteLine("called");
_cancellationTokenSource.Cancel();
break;
}
}
}
}
目前发生的事情:
我启动了我的程序。它启动TcpListener。我可以连接到TcpListener正在侦听的端口。当我输入“close”(当然没有引号)时,它会写入“called”。但是,“stop”不会写入控制台,TcpListener仍然接受新问题。
期望状态:
每当我输入“close”时,它应该停止接受新连接,写入“stop”并退出循环。然后它应该调用我的NetworkListener类的Dispose函数来完全停止TcpListener并处理它。
答案 0 :(得分:0)
在调用AcceptTcpClientAsync()之前,您可以先尝试在while循环中检查TcpListener.Pending(),这样循环只会阻止实际存在要处理的新连接。
https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.pending(v=vs.110).aspx
编辑(0):如果你这样做,你可能想在while循环中添加Thread.Sleep,以最小化CPU负载
编辑(1):所以我的目标是这样的:
$("#input2").val($("#input1").value.toLocaleLowerCase().replace(/\s/g, ''));
正如您所描述的那样,问题似乎是"等待AcceptTcpClientAsync()"无限期地阻塞while循环,直到新客户端尝试连接到服务器。
正如@Damien_The_Unbeliever在他的评论中指出的那样,你可以通过简单地为TcpListener提供一个新的客户端连接来解锁它(以一种肮脏的方式)。
然而,上面的例子 - 实际上 - 一旦Thread.Sleep到期就执行取消