.net - 如何检查(TCP)套接字是否在 C# 中(断开)连接?

标签 .net sockets

我应该如何检查(TCP)套接字以确定它是否已连接?

我已经阅读了Socket.Connected位于 MSDN 的房产,但它说它只显示根据最后一次 I/O 的状态。这对我没有用,因为我想在尝试从套接字读取之前执行此操作。备注部分还指出:

If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.



同一页上的示例显示了如何执行此操作。(1) 但是 a post by Ian Griffiths说我应该从套接字读取,而不是通过它发送。

Another post by Pete Duniho说:

... after you've called Shutdown(), call Receive() until it returns 0 (assuming the remote endpoint isn't actually going to send you anything, that will happen as soon as the remote endpoint has received all of your data). Unless you do that, you have no assurance that the remote endpoint has actually received all of the data you sent, even using a lingering socket.



我不太明白他关于调用 Receive() 的说法以确保远程端点实际上已收到我发送的所有数据。 (在发送缓冲区为空之前,套接字是否会阻塞接收?)

我对提出的不同方法感到困惑。你能解释一下吗?

(1) 我想知道为什么 example对于Socket.Connected属性分配一个 1 字节数组,即使它调用 Send长度为 0?

最佳答案

套接字的死亡会以多种方式改变其行为,因此这些方法都是有效的 :)

使用这两种方法,您实际上检查了断开连接后套接字行为的那些部分。

I don't really understand his statement about calling Receive() to make sure that the remote endpoint has actually received all the data I sent. (Do sockets block receiving until the sending buffer is empty?)


TCP是可靠的协议(protocol),这意味着您发送的每个数据包都必须得到确认。确认意味着发送带有 ACK 的数据包位设置。这些数据包可能包含也可能不包含附加(有效负载)数据。

当套接字连接时,Receive()将阻塞,直到套接字接收到具有非空有效负载的数据包。但是当socket断开时,Receive()将尽快返回 ACK数据包到达。

调用Receive()确保您收到最后一个 ACK来自远程端点的数据包或发生断开连接超时,您将无法在此套接字上接收更多信息。

The example on the same page shows how to do it. (I wonder why does it allocate a 1-byte array, even though it calls Send with 0 length?) But a post by Ian Griffiths says that I should read from the socket, not send through it.



send()连接到套接字时,您实际上尝试将一些数据附加到套接字队列的末尾。缓冲区中是否还有一些位置,然后您的Send()立即返回,如果没有,Send() block 直到有某个地方。

当套接字处于断开状态时,TCP/IP堆栈阻止对缓冲区的所有进一步操作,这就是 Send() 的原因返回错误。
Send()实现一个基本的指针检查,这意味着当一个 NULL 时它会失败。指针传递给它。您可能将任何非空常量作为指针传递,但您最好分配 1 个字节而不是创建常量 — 以防万一。

您可以使用任何您喜欢的方法,因为它们都不消耗资源。只要它们用于套接字连接检查,它们是相同的。

至于我,我更喜欢 Receive() ,因为这是您通常在一个循环中运行并等待的内容。你从 Receive() 得到一个非零值,您处理数据;你得到一个零,你处理断开连接。

关于.net - 如何检查(TCP)套接字是否在 C# 中(断开)连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/515458/

相关文章:

.Net 4.5 和 Azure

c++ - Boost - 在服务器关闭套接字上为新客户端 fork

ios - 同时使用套接字和 GameKit。大幅降低套接字速度

python - 套接字带外数据未作为 OOB 接收

c# - nunit-console 不运行使用 TestCase 属性参数化的测试

c# - 在短和字节之间转换的好方法?

c# - 在 C# 中如何收集程序崩溃的堆栈跟踪

java - kSoap2 发送集合

linux - ARP 表在 send() 调用期间/期间更改的影响

c++ - 程序关闭后套接字保持打开状态(C++)