首页 文章

你能在窗口上_close(),_ read()和_write()一个套接字吗?

提问于
浏览
3

MSDN说 closesocket() 是要使用的功能 . 但是,我不禁想知道 _close() 是否也会起作用?

MSDN似乎在他们对SOCKET类型的描述中说不:(http://msdn.microsoft.com/en-us/windows/ms740516(v=vs.80)):

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

更具体地说,来自note on renamed socket functions

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

但是,即使如上所述,一些Windows文件函数可能在实践中使用套接字:

鉴于ReadFileWriteFile在套接字上工作,我怀疑 _read_write ,例如,也可能适用于套接字和文件句柄 .

MSDN's overview of socket handles州:

套接字句柄可以选择是Windows套接字2中的文件句柄.Winsock提供程序的套接字句柄可以与其他非Winsock函数一起使用,如ReadFile,WriteFile,ReadFileEx和WriteFileEx .

2 回答

  • 2

    简短的回答是 no . Windows上的套接字句柄不是Unix上的文件句柄 . 有可能它结束的地方 .

    关于_open_osfhandle,是的,这可能会在非常有限的意义上起作用,但是你不应该这样做的原因很充分 . 以下大部分内容仅通过浏览CRT源代码中的open,read,write,close和open_osfhandle(Visual Studio附带)来推断 .

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

    • 表现 . 只需查看CRT源中的read()和write()源代码即可 . 最终调用ReadFile和WriteFile的很多包装代码,后者又转发到实际的socket API .

    • 套接字错误代码可能不会像您想象的那样冒泡到文件API . 记住通过WSAGetLastError返回socket API错误 . Win32文件IO调用通过GetLastError冒泡 . 因此,如果您对write()的调用遇到套接字错误,它可能会尝试通过GetLastError映射返回值,这仍然会返回成功 .

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

  • 2

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

    不,它们在Windows 3.x,9x中肯定是不同的:

    '在Windows 3.1和95中,Windows套接字和文件句柄完全不同 . 但是,在Windows NT中,看起来它们通常可能是同一个 .

    不,你不能在Windows NT上一起使用它们 - 至少在默认情况下不是这样:

    'Visual C RTL模拟POSIX函数,除了它们以前导下划线命名:例如,_ read()而不是read() . _read()函数在内部使用ReadFile(),因此您认为它适用于套接字 . 问题是,第一个参数是特定于RTL的句柄,而不是操作系统文件句柄 . 如果将套接字句柄传递给_read()或_write(),则RTL将意识到它不是RTL句柄,并且调用将失败 . “幸运的是,Visual C的RTL中有一个桥接函数:_open_osfhandle() . (如果你没有使用Visual C,你必须检查它的RTL源是否有类似的功能 . )我没有尝试过,但它似乎采用了一个操作系统文件句柄(包括套接字句柄)并返回一个处理您可以使用RTL中的POSIX仿真功能 . 我被告知这可以使用明确编码的非Microsoft Winsock堆栈,但由于我没有尝试过,所以如果你想支持这些备用堆栈,你应该这样做 .

相关问题