【发布时间】:2018-06-09 21:56:52
【问题描述】:
我正在使用 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”。但是,“停止”不会写入控制台,并且 TcpListener 仍在接受新问题。
所需状态:
每当我输入“关闭”时,它应该停止接受新连接,写入“停止”并退出循环。然后它应该调用我的 NetworkListener 类的 Dispose 函数来完全停止 TcpListener 并释放它。
【问题讨论】:
-
您的解释出了什么问题有点令人困惑(至少对我而言)您能否尝试通过编辑您的帖子/改写/添加更多解释来澄清这一点?您还可以查看how to create a minimal, complete, verifiable example 和how to ask 您可以尝试通过在currentState 下声明您的CurrentState 和在wanted state 下的WantedState 来解决您的问题。我想这可以帮助我理解你的问题 :) 欢迎来到 StackOverflow!
-
不完全确定,但您可能需要将
CancellationToken传递给AcceptTcpClientAsync -
@CamiloTerevinto - 不幸的是,没有过载可以接受。但你说得对,这就是症结所在。一种(丑陋的)解决方案是在取消后打开一个环回连接,以便我们知道
Accept任务将完成。 -
@CamiloTerevinto 不,据我所知,它不接受任何参数。
-
不幸的是,库中许多类的异步实现缺乏关键功能。只需关闭侦听器即可中止挂起的异步任务。
标签: c# asynchronous tcplistener