1

我正在尝试创建一个小型 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是,当空值被reader.ReadLineAsync().

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

4

1 回答 1

6

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

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

哦,而且TcpClient.Connected(like Socket.Connected) 实际上没用;它只告诉您套接字是否连接,而不是它是否连接。只是假装该财产不存在。

最后,有几点注意事项:

于 2013-04-22T02:09:15.293 回答