断开 TCPClient 并在另一端查看

发布于 2024-09-24 13:14:08 字数 1419 浏览 5 评论 0原文

我试图断开客户端与服务器的连接,但服务器仍然将其视为已连接。我找不到解决方案,“关机”、“断开连接”和“关闭”都不起作用。

我与客户端断开连接并检查服务器的一些代码:

客户端:

  private void btnDisconnect_Click(object sender, EventArgs e)
    {
        connTemp.Client.Shutdown(SocketShutdown.Both);
        connTemp.Client.Disconnect(false);
        connTemp.GetStream().Close();
        connTemp.Close();
    }

服务器:

    while (client != null && client.Connected)
            {
                NetworkStream stream = client.GetStream();
                data = null;

                try
                {
                    if (stream.DataAvailable)
                    {
                        data = ReadStringFromClient(client, stream);
                        WriteToConsole("Received Command: " + data);
                    }
                } // So on and so on...

代码中还有更多的写入和读取。

希望大家能够帮忙。

更新:我什至尝试通过 ref 传递 TCP 客户端,假设存在范围问题并且 client.Connected 即使在读取后仍然为 true。出了什么问题?

第二次更新!!:

这是解决方案。看一眼并据此确定您是否已连接。

  if (client.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] checkConn = new byte[1];
                        if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                        {
                            throw new IOException();
                        }
                    }

i am trying to disconnect a client from a server but the server still sees it as being connected. I cant find a solution to this and Shutdown, Disconnect and Close all dont work.

Some code for my disconnect from the client and checking on the server:

Client:

  private void btnDisconnect_Click(object sender, EventArgs e)
    {
        connTemp.Client.Shutdown(SocketShutdown.Both);
        connTemp.Client.Disconnect(false);
        connTemp.GetStream().Close();
        connTemp.Close();
    }

Server:

    while (client != null && client.Connected)
            {
                NetworkStream stream = client.GetStream();
                data = null;

                try
                {
                    if (stream.DataAvailable)
                    {
                        data = ReadStringFromClient(client, stream);
                        WriteToConsole("Received Command: " + data);
                    }
                } // So on and so on...

There are more writes and reads further down in the code.

Hope you all can help.

UPDATE: I even tried passing the TCP client by ref, assuming there was a scope issue and client.Connected remains true even after a read. What is going wrong?

Second Update!!:

Here is the solution. Do a peek and based on that, determine if you are connected or not.

  if (client.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] checkConn = new byte[1];
                        if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                        {
                            throw new IOException();
                        }
                    }

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

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

发布评论

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

评论(4

z祗昰~ 2024-10-01 13:14:08

这是解决方案!

  if (client.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] checkConn = new byte[1];
                    if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                    {
                        throw new IOException();
                    }
                }

Here is the solution!!

  if (client.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] checkConn = new byte[1];
                    if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                    {
                        throw new IOException();
                    }
                }
随梦而飞# 2024-10-01 13:14:08

来自 MSDN 文档< /a>:

Connected 属性获取
客户端套接字的连接状态
自上次 I/O 操作以来。

当它
返回 false,客户端套接字是
要么从未连接,要么没有
连接时间更长。因为
连接属性仅反映
截至目前的连接状态
最近的操作,你应该尝试
发送或接收消息
确定当前状态。之后
消息发送失败,该属性无
更长返回 true。请注意,这
行为是设计使然的。你不能
可靠地测试的状态
连接,因为,在当时
在测试和发送/接收之间,
连接可能已丢失。
您的代码应该假设套接字是
连接并优雅地处理
传输失败。

From the MSDN Documentation:

The Connected property gets the
connection state of the Client socket
as of the last I/O operation.

When it
returns false, the Client socket was
either never connected, or is no
longer connected. Because the
Connected property only reflects the
state of the connection as of the most
recent operation, you should attempt
to send or receive a message to
determine the current state. After the
message send fails, this property no
longer returns true. Note that this
behavior is by design. You cannot
reliably test the state of the
connection because, in the time
between the test and a send/receive,
the connection could have been lost.
Your code should assume the socket is
connected, and gracefully handle
failed transmissions.

夏了南城 2024-10-01 13:14:08

我不确定 NetworkStream 类,但我认为它的行为类似于 Socket 类,因为它主要是一个包装类。一般来说,服务器不会意识到客户端与套接字断开连接,除非它在套接字上执行 I/O 操作(读或写)。但是,当您在套接字上调用 BeginRead 时,直到有数据要从套接字读取时才会调用回调,因此调用 EndRead 并获取字节读取返回结果 0(零)意味着套接字已断开连接。如果您使用 Read 并获得零字节读取结果,我怀疑您可以检查基础 Socket 类上的 Connected 属性,如果客户端因在套接字上执行 I/O 操作而断开连接,则该属性将为 false。

I am not sure about the NetworkStream class but I would think that it would behave similar to the Socket class as it is primarily a wrapper class. In general the server would be unaware that the client disconnected from the socket unless it performs an I/O operation on the socket (a read or a write). However, when you call BeginRead on the socket the callback is not called until there is data to be read from the socket, so calling EndRead and getting a bytes read return result of 0 (zero) means the socket was disconnected. If you use Read and get a zero bytes read result I suspect that you can check the Connected property on the underlying Socket class and it will be false if the client disconnected since an I/O operation was performed on the socket.

梦行七里 2024-10-01 13:14:08

这是一个一般的 TCP 问题,请参阅:

此问题的解决方法往往依赖于发送作为协议一部分的预期数据量。这就是 HTTP 1.1 使用 Content-Length 标头(对于整个实体)或使用分块传输编码(具有不同的块大小)所做的事情。

另一种方法是定期发送“NOOP”或类似命令(本质上是不执行任何操作但确保通信仍然打开的消息)作为协议的一部分。

(您还可以在协议中添加客户端可以发送到服务器以彻底关闭连接的命令,但未收到该命令并不意味着客户端尚未断开连接。)

It's a general TCP problem, see:

The workaround for this tend to rely on sending the amount of data to expect as part of the protocol. That's what HTTP 1.1 does using the Content-Length header (for a entire entity) or with chunked transfer encoding (with various chunk sizes).

Another way is to send "NOOP" or similar commands (essentially messages that do nothing but make sure the communication is still open) as part of your protocol regularly.

(You can also add to your protocol a command that the client can send to the server to close the connection cleanly, but not getting it won't mean the client hasn't disconnected.)

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