如何断开 TcpClient 以允许新连接?

发布于 2024-10-14 21:22:52 字数 2142 浏览 1 评论 0原文

我有一个 TcpListener 等待新的套接字连接。当建立新连接时,一些其他代码会为来自远程用户的消息提供服务。我定期检查新连接,如果建立了新连接,则应删除旧连接。

以前我只是打开新连接,该连接在很大程度上工作正常。但有时,我在重新使用同一端口时会遇到问题,因此我认为关闭该连接会更好(我认为这也应该向旧用户表明连接已终止)。

下面的代码是我尝试这样做的,但由于某种原因 Disconnect 调用似乎无限期地阻塞。有办法阻止吗? ...或者我在这里还缺少其他东西吗?

while(1)
{
    // FYI, m_server is a TcpListener^ and m_client is a TcpClient^
        // Check for new client connections
    if (m_server->Pending() == true)
    {
        if( m_stream != nullptr )
        {
            m_client->Client->Shutdown( SocketShutdown::Both ); // Stop sending / receiving
            m_client->Client->Disconnect(true); // Disconnect the underlying network stream
            m_client->Client->Close(); // Disconnect the underlying network stream
            m_client->Close();
            delete m_client;
            m_client = nullptr;
        }

        m_client = m_server->AcceptTcpClient(); //grab the TCP client
        m_stream = m_client->GetStream();  //create the stream at the same time
    }

    // ...go and service pending messages on the client stream
}

有关 Disconnect() 函数的文档 建议我可以设置一个超时,但他们没有提到如何设置?

如果需要在不先调用 Shutdown 的情况下调用 Disconnect,则可以将 DontLinger Socket 选项设置为 false 并指定非零超时间隔,以确保发送排队等待传出传输的数据。然后 Disconnect 会阻塞,直到数据发送完毕或指定的超时到期。如果将 DontLinger 设置为 false 并指定零超时间隔,则 Close 会释放连接并自动丢弃传出排队数据。

[编辑] 我通过将 m_client->Client->Disconnect(true); 更改为 m_client->Client- 找到了超时问题的解决方案>Disconnect(false); 但这仍然没有警告我的客户套接字已关闭。我已经尝试了所有我能想到的测试方法,但它们都成功了:

// m_client is a TcpClient^
bool stillConnected = ( (m_client != nullptr) &&
                        (m_client->Connected == true) &&
                        (m_client->Client != nullptr) &&
                        (m_client->Client->Connected == true) );

即使在另一个客户端连接到服务器并因此调用上面的所有关闭点之后,stillConnected始终为真。就像我在问题顶部提到的关闭内容没有正确关闭套接字之类的?

I have a TcpListener which waits for new socket connections. When a new connection is made, some other code services messages from the remote user. I periodically check for new connections and if a new one is made, the old one should be dropped.

Previously I'd just open the new connection which for the most part worked okay. Occasionally though, I'd have problems re-using the same port so I figured it would be better to close that connection (which I think should also give the old user an indication that the connection died).

The code below is my attempt to do that, but for some reason the Disconnect call seems to block indefinitely. Is there a way of stopping that? ...or am I missing something else here?

while(1)
{
    // FYI, m_server is a TcpListener^ and m_client is a TcpClient^
        // Check for new client connections
    if (m_server->Pending() == true)
    {
        if( m_stream != nullptr )
        {
            m_client->Client->Shutdown( SocketShutdown::Both ); // Stop sending / receiving
            m_client->Client->Disconnect(true); // Disconnect the underlying network stream
            m_client->Client->Close(); // Disconnect the underlying network stream
            m_client->Close();
            delete m_client;
            m_client = nullptr;
        }

        m_client = m_server->AcceptTcpClient(); //grab the TCP client
        m_stream = m_client->GetStream();  //create the stream at the same time
    }

    // ...go and service pending messages on the client stream
}

The docs on the Disconnect() function suggest there's a timeout I can set but they don't mention how?

If you need to call Disconnect without first calling Shutdown, you can set the DontLinger Socket option to false and specify a nonzero time-out interval to ensure that data queued for outgoing transmission is sent. Disconnect then blocks until the data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.

[Edit] I found a solution to the timeout problem by changing m_client->Client->Disconnect(true); to m_client->Client->Disconnect(false); but that still doesn't warn my client that the socket has closed. I've tried everything I can think of to test but they all succeed:

// m_client is a TcpClient^
bool stillConnected = ( (m_client != nullptr) &&
                        (m_client->Connected == true) &&
                        (m_client->Client != nullptr) &&
                        (m_client->Client->Connected == true) );

stillConnected is always true even after another client has connected to the server and therefore called all the shutdown bits and pieces above. It's like the shutdown stuff I mentioned at the top of my question isn't closing the socket properly or something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜唯美灬不弃 2024-10-21 21:22:52

当读取返回成功且长度为零字节时,检测到 TCP 套接字断开连接(从远程端发送 FIN 标志)。

Disconnection of a TCP socket (FIN flag being sent from the remote end) is detected when a read returns success and a length of zero bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文