Sockets 你能在windows上关闭、读和写套接字吗?

Sockets 你能在windows上关闭、读和写套接字吗?,sockets,winapi,Sockets,Winapi,MSDN说closesocket()是要使用的函数。然而,我不禁想知道\u close()是否也能工作 MSDN在其对套接字类型()的描述中似乎表示不: 在Winsock应用程序中,套接字描述符不是文件描述符,必须与Winsock函数一起使用 更具体地说,从其: 在Berkeley Sockets中,套接字由标准文件描述符表示,因此close函数可用于关闭套接字以及常规文件。虽然Windows套接字中没有任何内容阻止实现使用常规文件句柄来标识套接字,但也没有任何内容需要它。在Windows上,必

MSDN说
closesocket()
是要使用的函数。然而,我不禁想知道
\u close()
是否也能工作

MSDN在其对套接字类型()的描述中似乎表示不:

在Winsock应用程序中,套接字描述符不是文件描述符,必须与Winsock函数一起使用

更具体地说,从其:

在Berkeley Sockets中,套接字由标准文件描述符表示,因此
close
函数可用于关闭套接字以及常规文件。虽然Windows套接字中没有任何内容阻止实现使用常规文件句柄来标识套接字,但也没有任何内容需要它。在Windows上,必须使用
closesocket
例程关闭套接字。在Windows上,使用
close
功能关闭套接字是不正确的,并且此规范未定义这样做的效果

但是,尽管存在上述情况,但某些Windows文件函数实际上可能与套接字一起工作:

考虑到这一点,我怀疑
\u read
\u write
,例如,它们也可以处理套接字和文件句柄

国家:

套接字句柄可以是Windows Sockets 2中的文件句柄。来自Winsock提供程序的套接字句柄可以与其他非Winsock函数一起使用,例如
ReadFile
WriteFile
ReadFileEx
writefilex


比MSDN更具洞察力:[http://tangentsoft.net/wskfaq/articles/bsd-compatibility.html]

不,它们在Windows 3.x和9x中绝对不同:

'在Windows 3.1和95中,Windows套接字和文件句柄是 完全不同。然而,在WindowsNT中,它们似乎通常是同一个

不,您不能在Windows NT上同时使用它们-至少默认情况下不能:

幸运的是,Visual C++的RTL中有一个桥函数: _打开_osfhandle()。(如果你不使用Visual C++,你必须检查它的RTL源以获得类似的功能。)我没有尝试过,但是 它似乎具有操作系统文件句柄(包括套接字) 句柄)并返回可用于POSIX仿真的句柄 RTL中的函数。有人告诉我,这将适用于sanely编码 非Microsoft Winsock堆栈,但由于我没有尝试过,您应该 如果您想支持这些备用堆栈。”


简而言之,答案是否定的。Windows上的套接字句柄不是Unix上的文件句柄。它提供了特殊的支持,使得低级Win32 API ReadFile和WriteFile可以与套接字句柄一起工作。但这很可能就是结局

关于“开放式”osfhandle,是的,这可能在非常有限的意义上起作用,但有充分的理由说明你不应该这样做。我只是通过浏览CRT源代码(VisualStudio附带的)中的open、read、write、close和open_osfhandle的源代码推断出以下大部分内容

  • CRT读/写调用中有很多缓冲区。任何将读/写与recv/send混合的尝试都将进入未定义的行为

  • 表演。只需查看CRT源代码中的read()和write()的源代码。大量的包装器代码最终调用ReadFile和WriteFile,而这又必须转发到实际的套接字API

  • 套接字错误代码可能不会像您认为的那样出现在文件API中。请记住,通过WSAGetLastError返回套接字API错误。Win32文件IO调用通过GetLastError冒泡。因此,如果对write()的调用遇到套接字错误,它可能会尝试通过GetLastError映射返回值,这仍然会返回success

  • close()无法正确关闭套接字句柄,因为它映射到的是CloseHandle,而不是closesocket


你的回答似乎是否定的,但随后你又拿出证据证明答案可能是肯定的。据推测,这些证据正是促使你首先提出这个问题的原因,所以也许你应该把它包括在问题中。我不觉得我现在比阅读答案前更接近于了解真相。谢谢。我更新了问题以反映反馈。我也找到了一些不同的答案。