我该如何检查(TCP)套接字是连接在C#(DIS)? [英] How can I check whether a (TCP) socket is (dis)connected in C#?

查看:250
本文介绍了我该如何检查(TCP)套接字是连接在C#(DIS)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该如何检查(TCP)套接字,找出是否连接?

How should I check a (TCP) socket to find out whether it is connected?

我已阅读有关 Socket.Connected 属性的 MSDN ,但它说,它只能根据最后的I / O显示状态。这是不适合我用,因为我想这样做的的努力从套接字读取。备注部分还注意到:

I have read about the Socket.Connected property in MSDN, but it says it only shows the state according to the last I/O. This isn't useful for me, since I want to do this before trying to read from the socket. The remarks section also notes that:

如果您需要确定目前的   连接的状态,使   非阻塞,零字节发送呼叫。如果   调用返回成功或   抛出一个WAEWOULDBLOCK错误code   (10035),则该插座仍   连接;否则,插座无   不再连接。

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)不过的后由伊恩·格里菲思说我应该的的从插座中,没有的通过它发送

The example on the same page shows how to do it.(1) But a post by Ian Griffiths says that I should read from the socket, not send through it.

<一个href="http://www.eggheadcafe.com/software/aspnet/33035784/cs-socketconnect-retur.aspx#ctl00_MiddleContent_NewsGroupPosts">Another后由皮特Duniho 说:

...你以后叫关机(),   叫接收(),直到它返回 0   (假设远程端点不   居然要送你什么,   将尽快发生,因为遥控器   端点已收到所有的   数据)。除非你这样做,你有   不保证远程端点   实际上已经接收到所有数据的   你送,甚至使用缠绵   插座。

... 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.

我真的不明白有关调用他的说法接收(),以确保远程端点已实际收到我的发送的所有数据。 (做插座模块接收到的发送缓冲区是空的?)

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?)

我对所提出的不同的方法混淆。能否请您解释一下呢?

I am confused by the different methods proposed. Could you please explain them?


(1)我不知道为什么例如了解在 Socket.Connected 财产分配1个字节数组,即使它调用发送 0的长度?

(1) I wonder why the example for the Socket.Connected property allocates a 1-byte array, even though it calls Send with 0 length?

推荐答案

插座之死改变它的行为在几个方面,所以这些方法都是有效的:)

Death of a socket changes its behavior in several ways, so these methods are both valid :)

使用这两种方法,你实际检查套接字的行为的部分断开后的改变。

With both methods you actually check those parts of the socket's behavior that change after disconnection.

我真的不明白他有关调用接收(),以确保远程终结点实际已全部我发送的数据的语句。 (做插座模块接收到的发送缓冲区是空的?)

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 是可靠的协议,这意味着你发送的每个数据包必须被确认。确认意味着与 ACK 位置发送数据包。这些分组可能或可能不包含额外的(有效负载)的内容

TCP is reliable protocol, that means that every packet you send must be acknowledged. Acknowledgement implies sending the packets with ACK bit set. These packets may or may not contain additional (payload) data.

当套接字连接,接收()将阻塞,直到套接字接收到带有非空有效载荷的数据包。但是,当插座断开,接收()将作为最后的 ACK 数据包到达后立即返回。

When the socket is connected, Receive() will block until the socket receives a packet with non-empty payload. But when the socket is disconnected, Receive() will return as soon as the last ACK packet arrives.

调用接收(),保证让你无论是的接收的,去年 ACK 从包远程终端或断开连接超时发生,你就可以的接收的无非在此套接字。

Calling Receive() ensures that you either receive that last ACK packet from your remote endpoint or a disconnect timeout occurs and you will be able to receive nothing more on this socket.

在同一页上的示例显示了如何做到这一点。 (我不知道为什么它分配一个1个字节数组,即使它调用发送0长度?),但后由伊恩·格里菲思说我应该从套接字读取,不发送通过它。

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.

发送()荷兰国际集团到一个插座,你真正尝试到一些数据追加到套接字队列的末尾。是否有留在缓冲区中的某个地方,那么你的发送()返回瞬间,如果没有,发送()块,直到有一些地方。

When send()ing to a socket, you actually try to append some data to the end of the socket queue. Is there is some place left in the buffer, then your Send() returns instantly, if not, the Send() blocks until there is some place.

当套接字处于断开状态, TCP / IP 堆栈prevents与缓冲区中的所有进一步的操作,这就是为什么发送() 返回一个错误。

When the socket is in disconnected state, TCP/IP stack prevents all further operations with the buffer, that's why Send() returns an error.

发送()实现了一个基本的指针检查,这意味着当一个 NULL 指针传递给它失败。您可能会可能会通过任何非空常量作为一个的指针,但你更好地分配,而不是使不断上升1个字节 - 以防万一

Send() implements a basic pointer check, this means it fails when a NULL pointer is passed to it. You may probably pass any non-null constant as a pointer, but you better allocate 1 byte instead of making the constant up — just in case.


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

You may use any method you like, as none of them is resource consuming. As long as they are used for socket connection checking, they are identical.

至于我,我会preFER 接收(),因为这是你在一个周期内正常运行,并等待。你得到一个非零从接收(),您处理数据;你会得到一个零,你处理断线。

As for me, I would prefer Receive(), as this is what you normally run in a cycle and wait for. You get a non-zero from Receive(), you process data; you get a zero, you process disconnection.

这篇关于我该如何检查(TCP)套接字是连接在C#(DIS)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆