如何检测telnet客户端是否不正确地关闭了tcp服务器

本文关键字:正确地 不正确 服务器 tcp 是否 客户端 何检测 检测 telnet | 更新日期: 2023-09-27 18:10:19

我正在尝试创建一个小型IRC服务器,以学习一些新的编程概念(以及一些我永远不会使用的概念)。第一步是让一个基本的客户端通过TCP连接,向服务器发送明文命令。

监听连接,我有以下代码:

public NetworkClient(Server server, TcpClient socket, int id)
{
    _socket = socket;
    _id = id;
    _server = server;
}
private async void ListenForClients()
{
    int numClients = 0;
    while (IsRunning)
    {
        var tcpClient = await _listener.AcceptTcpClientAsync();
        var netClient = new NetworkClient(this, tcpClient, numClients);
        netClient.Start();
        Console.WriteLine("Client Connected");
        numClients++;
    }
}

然后在我的NetworkClient类我的Start()方法看起来像:

public async void Start()
{
    using (var reader = new StreamReader(_socket.GetStream()))
    {
        while (_server.IsRunning)
        {
            var line = await reader.ReadLineAsync();
            Console.WriteLine("Client {0} wrote: {1}", _id, line);
        }
    }
}

这工作得很好,而telnet客户端连接,但是一旦我关闭我的telnet客户端reader.ReadLineAsync();不断返回null。我会添加一个检查,看看是否line == null,但我不确定这是检测客户端是否已断开连接的正确方法。

更糟糕的是,_socket.Connected不断返回true,而reader.ReadLineAsync()正在"接收"null。

检测tcp客户端何时断开连接的正确方法是什么?

如何检测telnet客户端是否不正确地关闭了tcp服务器

在TCP/IP套接字上读取将在连接优雅关闭时返回0字节。这种情况导致ReadLineAsync返回null。所以,是的,您应该检查null并将其视为优雅的套接字关闭。

套接字也可以通过其他方式关闭;如果套接字被无效关闭,任何套接字操作都可能抛出异常。如果异常发生在协议的可接受部分(关闭不被认为是错误),那么您应该将该异常视为一个优雅的关闭。

哦,TcpClient.Connected(和Socket.Connected一样)实际上是无用的;它只告诉您套接字是否已连接,而不告诉您套接字是否已连接。就当这个属性不存在。

最后,几个注意事项:

  • 避免async void。如果你的方法返回Task,那么你有一个"句柄"来查看它们何时完成(以及它们是否引发异常)。我最近的MSDN文章解释了为什么不推荐async void
  • 最好定期通过连接发送数据,以确定它是否仍然可行。我写了一个TCP/IP . net套接字FAQ,详细介绍了这个问题。