Differences Between Windows and Unix Non-Blocking Sockets

http://itamarst.org/writings/win32sockets.html

 

Differences Between Windows and Unix Non-Blocking Sockets



While working on Twisted's networking, I discovered a series of differences between socket APIs on Windows and Unix/Linux. This page is intended to document them for the benefit of those who are developing their own networking code. Some caveats:
This document only discusses non-blocking sockets.
I am not an expert on Unix, Windows or networking. On the other hand Twisted has an extensive set of tests and runs numerous real programs on both platforms.
These results were based on Python's behavior, as is my terminology. Since Python wraps the C APIs in a very lightweight way, and I haven't seen any differences between its behavior and MSDN and Unix documentation, this information is almost certainly valid for C networking code as well.

My main sources of information were the relevant MSDN pages, Volume 1 of Unix Network Programming (2nd Edition), and experimentation and results from running systems. I recommend all three for verifying this information.

For more differences see Warren Young's BSD Sockets Compatibility page.
select(2) limited to 64 FDs on Windows
In order to fix this, you can do #define FD_SETSIZE 512 (or some larger number if you wish). Python does this for you already.
WSA errnos
Socket APIs will return WSA errnos, rather than the standard ones (e.g. WSAEWOULDBLOCK, although Windows also has EWOULDBLOCK). Except when they don't. Refer to MSDN.
select(2) doesn't block on empty lists of fds
If you don't pass any socket fds to select(2) on Unix, it will block for the specified timeout. On Windows, it will return immediately with an error. This may be a Python oddity.
Peculiar errnos from select(2)
I've seen errnos 0 and 2 returned on Win32 for no reason I understood, apparently when passing empty read or write list.
Detecting failed connects is done using exception list of select(2)
On Unix, a failed connect will return an error upon reading or writing from the socket, and select() will mark the socket as notified. The exception list in select(2) is used for detecting OOB data. On Windows, not the read or write lists but rather the exception list is used for detecting failed connects.
On Windows failed connects, reads and writes still return WSAEWOULDBLOCK
Reads or writes to the socket will return a WSAEWOULDBLOCK even if connection failed. The errno is available via getsockopt with SO_ERROR.
WSAEINVAL is equivalent to WSAEWOULDBLOCK for connect(2)
You need to treat both as equivalent on Windows. (This makes me suspicious after rereading issue before previous, might be untrue and I screwed up somewhere - verify this sometime.)
SO_REUSEADDR is weird
On Windows it lets you bind to the same TCP port multiple times without errors. Verified experimentally by failing test, I never bothered to check out MSDN docs for this one, I just don't use it on Windows.
UDP blocking on recvfrom returns WSAECONNRESET for connection refused
On Unix you get ECONNREFUSED.
Differences in partial writes to TCP sockets (contributed by James Knight).
In Unix, socket.send(buf) will buffer as much of buf as it has space for, and then return how much it accepted. This could be 0 or up to something around 128K. If you send some data and then some more, it will append to the previous buffer.

In Windows, socket.send(buf) will either accept the entire buffer or raise ENOBUFS. Testing indicates that it will internally buffer any amount up to 50MB (this seems to be the total for either the process or the OS, I'm not sure). However, it will not incrementally accept more data to append to a socket's buffer until the big buffer has been completely emptied (seemingly down to the SO_SNDBUF length, which is 8192), but rather raises WSAEWOULDBLOCK instead.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值