您的位置:首页 > 编程语言 > Java开发

Java,在Windows平台上使用Socket.sendUrgentData() 来检查连接有效性是不可靠的

2015-01-03 17:44 721 查看
在Windows平台上使用Socket.sendUrgentData() 来检查连接有效性是不可靠的。除非使用OOBInline。

原文:http://www.serverframework.com/asynchronousevents/2011/10/out-of-band-data-and-overlapped-io.html

TCP Urgent Data

In TCP out of band data is implemented in terms of 'urgent data' using the URG bit and the Urgent Pointer, see

here, however, there are two conflicting descriptions of how this works,
RFC 793 which details TCP says that the Urgent Pointer indicates the byte that follows the urgent data but

RFC 1122 corrects this and states that the Urgent Pointer indicates the final byte of urgent data. This leads to interoperability issues if one peer uses the RFC 793 definition and the other uses the RFC 1122 definition. The Windows documentation for the
standard TCP Winsock Provider claims that it operates as BSD does however this can be changed using the
TCP_EXPEDITED_1122
socket option if the Winsock provider supports it. There's more compatibility complexity in that Windows only supports a single byte of out of band data whereas RFC 1122 specifies that TCP MUST support sequences of urgent data
bytes of any length. Windows also doesn't specify how or if it will buffer subsequent out of band data, so if you are slow in reading a byte of urgent data and another byte of urgent data arrives then one of the bytes may be lost; though our tests have shown
that Windows does buffer urgent data. This all makes the use of out of band signalling using urgent data somewhat unreliable on Windows with TCP.

The unreliability shows itself if you're using separate OOB reads using
MSG_OOB
. In this instance you may get the 'wrong' byte of OOB data if you are dealing with a peer that implements the altenative RFC. This wouldn't be a problem if the byte hadn't been removed from the normal data stream and so you end up with an incorrect
byte in the normal data stream (the intended OOB byte) and a missing byte, which has been treated as OOB data. This doesn't cause problems for the two traditional users of TCP Urgent Data, Telnet and Rlogin as they simply use the Urgent data notification to
alert the server that urgent data is present in the data stream and then read and discard all of the normal data in the stream until they can read the urgent data. See here for how this facility is used in

the Telnet protocol's synch function. It's practically impossible to implement this functionality with overlapped I/O as you don't want the urgent data removed from the data stream, so you need to operate in
SO_OOBINLINE
mode and yet when in that mode you will never be notified that urgent data exists. To implement the telnet model with overlapped I/O you pretty much need to always read all inbound data and buffer it in your server rather than allowing
it to buffer in the TCP stack and allowing TCP flow control to prevent the client from sending more until you're ready.

So, if you want to use out of band data with TCP with overlapped I/O you need to remember five things:
Out of band data in TCP on Windows when interoperating with other, non-Windows, operating systems is likely to be unreliable due to differences between RFC 793 and RFC 1122.
Expecting to send more than a single byte of out of bound data is likely not to work.
Your out of band data may get "lost" if you send out of band data faster than the receiver is processing it.
To read out of band data using overlapped I/O you need to post a special
WSARecv()
with
MSG_OOB
set in the flags.
Real out of band communication using TCP is better achieved with a separate 'control' connection rather than using TCP's Urgent data function via
MSG_OOB
.

Despite all of this, The Server Framework will support out of band data in the next major release. By default OOB data will be disabled and we'll abort connections that use it. You can also decide to enable OOB inline which effectively disables OOB data from
the receiver's point of view and simply keeps the out of band data in the main data stream. Or, you can enable async OOB which will read OOB data using an optional special purpose overlapped read with
MSG_OOB
set.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐