繁体   English   中英

C中send()的最大size_t值

[英]max size_t value on send() in C

我正在用C语言编写一个TCP服务器,但是在发送时遇到了问题。 我读取本地文件并将数据发送回客户端,当文件较小时,我没有问题,但是当文件较大时,我遇到了这种奇怪的情况:

服务器tcp:

 // create socket, bind, listen accept

// read file
fseek(fptr, 0, SEEK_SET);
// malloc for the sending buffer
ssize_t read = fread(sbuf, 1, file_size, fptr);

while(to_send>0) {
  sent = send(socket, sbuf, buf_size, 0);
  sbuf += sent;
  to_send -= sent;
}

在发送的巨大文件上,它等于size_t的最大值,我认为我有缓冲区溢出。 我该如何预防? 从文件读取并将其发送回的最佳实践是什么?

问题是,即使没有那么多的buf_size ,您每次都发送buf_size字节。

例如,假装buf_size为8,则您要发送10个字节(因此最初, to_send也是10)。 第一次send发送8个字节,因此您需要再发送2个字节。 第二次,您还发送8个字节(可能超出范围)。 然后, to_send将为-6,与SIZE_MAX - 5相同。

一个简单的解决方法是发送to_send如果较小):

sent = send(socket, sbuf, to_send < buf_size ? to_send : buf_size, 0);

另外,如果send失败,则send返回-1 分配给size_t时,这与SIZE_MAX相同。 您将需要一些错误处理才能解决此问题。

在发送的巨大文件上,它等于size_t的最大值,我认为我有缓冲区溢出。

由于sent的值作为send()的返回值,并且send()返回ssize_t ,这是一个有符号的类型,不可能比size_t宽,因此实际上可以确定,实际发生的事情是send()表示一个通过返回-1表示错误。 在这种情况下,还将errno为指示错误的值。 在我曾经使用过的任何系统上,它都无法返回size_t的最大值。

我该如何预防?

首先,在担心阻止它之前,请务必确保通过以下方式对其进行检测

  1. 声明sent作为ssize_t来匹配send()的返回类型,而不是size_t ,并且
  2. 检查返回到值sent用于这种错误条件。

其次,如果您处理文件的时间实际上超过了ssize_t所能表示的ssize_t (远小于size_t ),那么在发送任何内容之前将其全部加载到内存中是一个糟糕的主意。 取而代之的是,将其装入(很多)较小的块中,然后一次发送一个这样的块中的数据。 这不仅会降低感知延迟,而且还能避免与接近所涉及数据类型的限制相关的任何风险。

此外,当您这样做时,请小心正确地做。 您已经很好地将send()调用包装在了一个循环中,以应对简短的写操作,但是正如@Artyer在他的答案中所描述的那样,您并没有完全正确,因为您没有减少尝试发送的字节数在第二次及以后的通话中。

从文件读取并将其发送回的最佳实践是什么?

如上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM