断开 TCPClient 并在另一端查看
我试图断开客户端与服务器的连接,但服务器仍然将其视为已连接。我找不到解决方案,“关机”、“断开连接”和“关闭”都不起作用。
我与客户端断开连接并检查服务器的一些代码:
客户端:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是解决方案!
Here is the solution!!
来自 MSDN 文档< /a>:
From the MSDN Documentation:
我不确定 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.
这是一个一般的 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.)