gpt4 book ai didi

c - 在套接字库中调用 recv 时,我的 recv 缓冲区应该有多大

转载 作者:太空狗 更新时间:2023-10-29 16:14:31 24 4
gpt4 key购买 nike

我有几个关于 C 中的套接字库的问题。这是我将在问题中引用的代码片段。

char recv_buffer[3000];
recv(socket, recv_buffer, 3000, 0);
  1. 我如何决定接收缓冲区的大小?我正在使用 3000,但它是任意的。
  2. 如果 recv() 收到一个比我的缓冲区大的数据包会怎样?
  3. 如果不再次调用 recv 并让它在没有任何可接收的情况下一直等待,我怎么知道我是否已收到整个消息?
  4. 有没有办法让缓冲区没有固定的空间量,这样我就可以不断地添加它而不用担心空间不足?也许使用 strcat 将最新的 recv() 响应连接到缓冲区?

我知道这是一个问题很多,但我将不胜感激任何答复。

最佳答案

这些问题的答案取决于您使用的是流套接字 (SOCK_STREAM) 还是数据报套接字 (SOCK_DGRAM) - 在 TCP/IP 中,前者对应TCP,后者对应UDP。

您如何知道将缓冲区传递给 recv() 有多大?

  • SOCK_STREAM:其实没什么太大关系。如果您的协议(protocol)是事务性/交互式协议(protocol),只需选择一个可以容纳您合理期望的最大单个消息/命令的大小(3000 可能没问题)。如果您的协议(protocol)正在传输大量数据,那么更大的缓冲区可能更有效 - 一个好的经验法则是与套接字的内核接收缓冲区大小大致相同(通常约为 256kB)。

  • SOCK_DGRAM:使用足够大的缓冲区来容纳您的应用程序级协议(protocol)曾经发送过的最大数据包。如果您使用的是 UDP,那么通常您的应用程序级协议(protocol)不应发送大于 1400 字节的数据包,因为它们肯定需要分段和重新组装。

如果 recv 得到一个大于缓冲区的数据包会怎样?

  • SOCK_STREAM:这个问题并没有真正的意义,因为流套接字没有数据包的概念——它们只是连续的字节流。如果可供读取的字节数多于缓冲区的空间,则它们将由操作系统排队,并可供您下次调用 recv

  • SOCK_DGRAM:丢弃多余的字节。

我怎么知道我是否收到了整封邮件?

  • SOCK_STREAM:您需要在应用程序级协议(protocol)中构建某种确定消息结束的方法。通常这是一个长度前缀(每条消息以消息的长度开始)或消息结束定界符(例如,它可能只是基于文本的协议(protocol)中的换行符)。第三种较少使用的选项是为每条消息规定固定大小。这些选项的组合也是可能的 - 例如,包含长度值的固定大小的 header 。

  • SOCK_DGRAM:单个 recv 调用始终返回单个数据报。

有没有办法让缓冲区没有固定的空间量,这样我就可以不断地向它添加内容而不用担心空间不足?

没有。但是,您可以尝试使用 realloc() 调整缓冲区大小(如果它最初是用 malloc()calloc() 分配的,那是)。

关于c - 在套接字库中调用 recv 时,我的 recv 缓冲区应该有多大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2862071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com