![](/img/trans.png)
[英]static size_t strnlen(const char *s, size_t max) — why a static return value?
[英]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
的最大值。
我该如何预防?
首先,在担心阻止它之前,请务必确保通过以下方式对其进行检测 :
sent
作为ssize_t
来匹配send()
的返回类型,而不是size_t
,并且 sent
用于这种错误条件。 其次,如果您处理文件的时间实际上超过了ssize_t
所能表示的ssize_t
(远小于size_t
),那么在发送任何内容之前将其全部加载到内存中是一个糟糕的主意。 取而代之的是,将其装入(很多)较小的块中,然后一次发送一个这样的块中的数据。 这不仅会降低感知延迟,而且还能避免与接近所涉及数据类型的限制相关的任何风险。
此外,当您这样做时,请小心正确地做。 您已经很好地将send()
调用包装在了一个循环中,以应对简短的写操作,但是正如@Artyer在他的答案中所描述的那样,您并没有完全正确,因为您没有减少尝试发送的字节数在第二次及以后的通话中。
从文件读取并将其发送回的最佳实践是什么?
如上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.