【问题标题】:Why is there no 64-bit API for winsock?为什么 winsock 没有 64 位 API?
【发布时间】:2020-07-10 18:26:17
【问题描述】:

Winsock API 中的 send()sendto() 等调用采用原始 int 来指示其缓冲区参数的大小。这显然对可以发送的最大缓冲区大小设置了 32 位限制。

这是为什么?是否有可用的 64 位 Winsock2 API 可能使用更合适的大小类型(例如 size_t)?

在 Linux 上,类似的调用使用 size_t 类型来定义大小。

【问题讨论】:

  • 您想在一次通话中发送超过 4GB 的数据?!
  • FWIW 在所有平台上int 的大小不一定是 4 字节stackoverflow.com/questions/589575/… 尽管在使用 Visual Studio 的 Windows 上就是这种情况docs.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=vs-2019
  • 大概是因为发送大于 2 GB 的消息并不常见。
  • 在不同的非 Windows 平台上,这些调用曾经使用 intunsigned int 作为尺寸类型,但是这已经改变了。在 Windows 上,更改大小类型会破坏现有应用程序的二进制兼容性。
  • 这个问题似乎来自对套接字如何工作的误解。即使您使用 1MB 调用 send(),对另一端的 recv() 的调用也可能会收到从 1 字节到完整 1MB 的任何内容,并且可能必须再次调用 recv()。在对套接字进行编程时,您必须告诉接收者要接收多少或使用结束标记。所以你看,在发送数据时,通过多次调用发送它们不是问题。

标签: c++ c tcp 64-bit winsock2


【解决方案1】:

不需要更大尺寸的函数,实际上类型可以很短,但它仍然没有问题。

套接字不发送消息,它们只是传输字节。当您调用 send() 时,可能不会在 recv() 调用中以一个块的形式接收数据。您必须在接收字节时实现逻辑才能知道您是否全部收到,如果没有,请再次调用 recv()。所以如果你想发送比 int 更大的东西?只需多次调用 send()。如果你的 recv() 代码不能处理这个问题,那就是一个错误,因为它应该这样做。

【讨论】:

  • 没错。 send()sendto() 在一次调用中发送的字节数不太可能超过套接字缓冲区的容量,后者远小于 2 GiB。数据传输大小也可能受到各种其他因素的限制。调用这些函数的用户代码必须检查实际发送了多少字节,并准备使用多次调用来发送多个字节,除非它实际上并不关心有多少数据是已发送。
  • 是的,这在 Linux 上不同的唯一原因是发送/接收基本上是写入/读取。
  • @Fredrik - 我非常了解套接字的工作原理,但感谢您的复习:) 问题是为什么 API 从未更改为支持 64 位接口。这样做的结果是无数“警告 C4267:'argument':从 'size_t' 转换为 '...',可能丢失数据”错误,当从更高级别调用时。
猜你喜欢
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
相关资源
最近更新 更多