【问题标题】:How do I detect when a telnet client is improperly closed to a tcp server?如何检测 telnet 客户端何时不正确地关闭 tcp 服务器?
【发布时间】:2013-04-22 10:31:35
【问题描述】:

我正在尝试创建一个小型 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()“接收”空值。

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

【问题讨论】:

    标签: c# tcplistener


    【解决方案1】:

    当连接正常关闭时,对 TCP/IP 套接字的读取将返回 0 字节。 This situation causes ReadLineAsync to return null. 所以,是的,您应该检查 null 并将其视为优雅的套接字关闭。

    套接字也可以通过其他方式关闭;如果套接字被异常关闭,任何套接字操作都可能引发异常。如果异常发生在协议的可接受部分(其中关闭不被视为错误),那么您应该将该异常视为正常关闭。

    哦,TcpClient.Connected(如Socket.Connected)实际上没用; it only tells you whether the socket was connected, not whether it is connected。假装该属性不存在。

    最后,几点说明:

    • 避免async void。如果您的方法返回Task,那么您有一个“句柄”来查看它们何时完成(以及它们是否引发异常)。我的recent MSDN article 解释了为什么不推荐使用async void
    • 最好定期通过连接发送数据以确定它是否仍然可行。我写了一个TCP/IP .NET sockets FAQ 那个covers this in more detail

    【讨论】:

    • 太好了,也感谢您的资源!我对async/await 和套接字都是新手,所以这些肯定会派上用场。
    猜你喜欢
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2013-04-15
    • 2010-09-19
    相关资源
    最近更新 更多