这个问题的简单答案是否定的。看看MSDN上对SOCKET值的描述[1]:
Windows 套接字句柄没有任何限制,除了值 INVALID_SOCKET 不是有效套接字之外。套接字句柄可以采用 0 到 INVALID_SOCKET–1 范围内的任何值。
很明显,API 允许在 64 位 Windows 上使用 [0, 2^64 - 1) 范围内的所有值。如果 API 返回的值大于 2^32 - 1,则将其分配给 int 将导致句柄截断。另请看一下 socket() 函数返回值的描述 [2]:
如果没有发生错误,套接字将返回引用新套接字的描述符。
注意到它最强调地不承诺返回内核句柄。这使得有关内核句柄的可能值的任何讨论都毫无意义。
话虽这么说,截至撰写本文时,socket() 函数确实返回了一个内核句柄(或与内核句柄无法区分的东西)[3],并且内核句柄实际上仅限于 32 位 [4]。但请记住,微软明天可能会改变任何这些事情,而不会破坏他们的界面合同。
然而,由于毫无疑问大量应用程序已经依赖于这些特定的实现细节(更重要的是,OpenSSL 也是如此),因此 Microsoft 可能会在做出任何重大更改时三思而后行。因此,继续将 SOCKET 转换为 int。请记住,这本质上是一种危险的、糟糕的做法,并且永远不能以权宜之计的名义进行合理化。
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516(v=vs.85).aspx
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms742295(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms742295(v=vs.85).aspx
- http://msdn.microsoft.com/en-us/library/windows/desktop/aa384267(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/aa384267(v=vs.85).aspx
编辑(2018-01-29)
由于这个主题似乎仍然令人感兴趣,因此值得指出的是,在 C++11 中编写可移植套接字代码非常容易,而无需诉诸有问题的类型转换:
using socket_t = decltype(socket(0, 0, 0));
socket_t s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);