简体   繁体   English

C# - 从客户端检查 TCP/IP 套接字状态

[英]C# - Check TCP/IP socket status from client side

I'd like to provide my TCP/IP client class with a CheckConnection function so that I can check if something wrong has happened (my own client disconnected, server disconnected, server stuck up,...).我想为我的 TCP/IP 客户端类提供 CheckConnection 函数,以便我可以检查是否发生了错误(我自己的客户端断开连接、服务器断开连接、服务器卡住了……)。
I have something like that:我有这样的事情:

bool isConnectionActive = false;
if (Client.Poll(100000, SelectMode.SelectWrite) == true)
  isConnectionActive = true;

based on what MSDN says:根据 MSDN 所说:

SelectWrite: true, if processing a Connect(EndPoint), and the connection has succeeded; SelectWrite: true,如果处理一个Connect(EndPoint),并且连接成功; -or- true if data can be sent; - 或 - 如果可以发送数据,则为真; otherwise, returns false.否则,返回 false。

The point is that, testing this with simple server application, I am getting always true from CheckConnection, even if server-listener has been closed and even if server-application has been shutdown;关键是,使用简单的服务器应用程序对此进行测试时,即使服务器侦听器已关闭并且服务器应用程序已关闭,我也始终从 CheckConnection 获得正确结果; that's weird, because I expect in those cases that both no connection is being processed (already connected minutes ago) and no data can be sent.这很奇怪,因为我希望在这些情况下没有连接正在处理(几分钟前已经连接)并且没有数据可以发送。

I have already implemented a similar connection check on server side using a combination of Poll with SelectRead and Available and it seems working properly;我已经使用 Poll 与 SelectRead 和 Available 的组合在服务器端实现了类似的连接检查,它似乎工作正常; so now, should I write something similar also on client side?所以现在,我应该在客户端也写一些类似的东西吗? is the SelectWrite approach correct (but I'm using it improperly)? SelectWrite 方法是否正确(但我使用不当)?

There are lots of things you can check but none of them are assured to give you the result you are looking for.有很多事情你可以检查,但没有一个能保证给你你正在寻找的结果。 Even the implementation you have on the server will not work 100% of the time.即使您在服务器上的实现也不能 100% 地工作。 I guarantee it will fail one day.我保证有一天它会失败。

There are FIN packets, which should be sent from the client to the server, and vice versa when a connection is closed, but there is no guarantee that these will be delivered, or even processed.有 FIN 数据包,它们应该从客户端发送到服务器,反之亦然,当连接关闭时,但不能保证这些数据包会被传递,甚至被处理。

This is generally known as the TCP Half Open problem.这通常称为TCP 半开放问题。

Closing a TCP Socket is a mutually agreed process, you generally have a messaging protocol which tells the other end that it's closing, or you have some predefined set of instructions and you close after that.关闭 TCP 套接字是一个双方同意的过程,您通常有一个消息传递协议告诉另一端它正在关闭,或者您有一些预定义的指令集,然后您关闭。

The only reliable way to 100% detect if a remote socket is closed is to send some data to it. 100% 检测远程套接字是否关闭的唯一可靠方法是向其发送一些数据。 Only if you get an error back will you know if the socket has closed.只有当您收到错误消息时,您才会知道套接字是否已关闭。

Some applications which don't send a lot of data implement a keep-alive protocol, they simply send/receive a few bytes every minute, so they know that the remote endpoint is present.一些不发送大量数据的应用程序实现了保持活动协议,它们只是每分钟发送/接收几个字节,因此它们知道远程端点存在。

You can technically have two servers that are in a connected state and haven't sent data to each other for 10 years.从技术上讲,您可以拥有两台处于连接状态且 10 年未相互发送数据的服务器。 Each end continues to believe that the other end is there until one try's to send some data and finds out it isn't.每一端都继续相信另一端在那里,直到尝试发送一些数据并发现它不在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM