在套接字库中调用 recv 时,我的 recv 缓冲区应该有多大 [英] How large should my recv buffer be when calling recv in the socket library

查看:33
本文介绍了在套接字库中调用 recv 时,我的 recv 缓冲区应该有多大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个关于 C 语言套接字库的问题.这是我在问题中会参考的一段代码.

I have a few questions about the socket library in C. Here is a snippet of code I'll refer to in my questions.

char recv_buffer[3000];
recv(socket, recv_buffer, 3000, 0);

  1. 我如何决定使 recv_buffer 有多大?我正在使用 3000,但它是任意的.
  2. 如果 recv() 收到比我的缓冲区大的数据包会怎样?
  3. 如何知道我是否在没有再次调用 recv 的情况下收到了整条消息,并在没有收到任何消息时让它永远等待?
  4. 有没有办法让缓冲区没有固定的空间量,这样我就可以继续添加它而不必担心空间不足?也许使用 strcat 将最新的 recv() 响应连接到缓冲区?
  1. How do I decide how big to make recv_buffer? I'm using 3000, but it's arbitrary.
  2. what happens if recv() receives a packet bigger than my buffer?
  3. how can I know if I have received the entire message without calling recv again and have it wait forever when there is nothing to be received?
  4. is there a way I can make a buffer not have a fixed amount of space, so that I can keep adding to it without fear of running out of space? maybe using strcat to concatenate the latest recv() response to the buffer?

我知道其中有很多问题,但如果您能得到任何答复,我将不胜感激.

I know it's a lot of questions in one, but I would greatly appreciate any responses.

推荐答案

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

The answers to these questions vary depending on whether you are using a stream socket (SOCK_STREAM) or a datagram socket (SOCK_DGRAM) - within TCP/IP, the former corresponds to TCP and the latter to UDP.

你怎么知道传递给recv()的缓冲区有多大?

How do you know how big to make the buffer passed to recv()?

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

  • SOCK_STREAM: It doesn't really matter too much. If your protocol is a transactional / interactive one just pick a size that can hold the largest individual message / command you would reasonably expect (3000 is likely fine). If your protocol is transferring bulk data, then larger buffers can be more efficient - a good rule of thumb is around the same as the kernel receive buffer size of the socket (often something around 256kB).

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

SOCK_DGRAM: Use a buffer large enough to hold the biggest packet that your application-level protocol ever sends. If you're using UDP, then in general your application-level protocol shouldn't be sending packets larger than about 1400 bytes, because they'll certainly need to be fragmented and reassembled.

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

What happens if recv gets a packet larger than the buffer?

  • SOCK_STREAM:这个问题实际上没有意义,因为流套接字没有数据包的概念——它们只是一个连续的字节流.如果可供读取的字节数超过了缓冲区的空间,那么它们将被操作系统排队,供您下次调用 recv 时使用.

  • SOCK_STREAM: The question doesn't really make sense as put, because stream sockets don't have a concept of packets - they're just a continuous stream of bytes. If there's more bytes available to read than your buffer has room for, then they'll be queued by the OS and available for your next call to recv.

SOCK_DGRAM:多余的字节被丢弃.

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

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

  • SOCK_STREAM: You need to build some way of determining the end-of-message into your application-level protocol. Commonly this is either a length prefix (starting each message with the length of the message) or an end-of-message delimiter (which might just be a newline in a text-based protocol, for example). A third, lesser-used, option is to mandate a fixed size for each message. Combinations of these options are also possible - for example, a fixed-size header that includes a length value.

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

SOCK_DGRAM: An single recv call always returns a single datagram.

有没有办法让缓冲区没有固定的空间量,这样我就可以继续添加它而不必担心空间不足?

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

No. However, you can try to resize the buffer using realloc() (if it was originally allocated with malloc() or calloc(), that is).

这篇关于在套接字库中调用 recv 时,我的 recv 缓冲区应该有多大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆