我正在用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的最大值时,我认为我有缓冲区溢出。我该如何预防?从文件读取并将其发送回去的最佳实践是什么?
答案 0 :(得分:3)
问题是,即使没有多少字节,您也每次发送[1, 1, 4, 2, 1, 1, 0, 0]
个字节。
例如,假设stack.pop()
为8,而您正在发送10个字节(因此,最初,public class DailyTemperatures {
public int[] dailyTemperatures(int[] temperatures) {
int[] res = new int[temperatures.length];
Stack<Integer> stack = new Stack();
for (int i = 0; i < temperatures.length; i++) {
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int index = stack.pop();//this line is my query
res[index] = i - index;
}
stack.push(i);
}
for (int i : res) {
System.out.println(" "+ i);
}
return res;
}
public static void main(String[] args) {
DailyTemperatures dailyTemperatures=new DailyTemperatures();
int [] temp={73, 74, 75, 71, 69, 72, 76, 73};
dailyTemperatures.dailyTemperatures(temp);
}
}
也为10)。前一个 if ( searchedText.count > 0 ) {
if searchedText.lowercased() == "full" {
fetchRequest.predicate = NSPredicate(format: "ANY projectColours.fullLeft > 0")
} else if searchedText.lowercased() == "partial" {
fetchRequest.predicate = NSPredicate(format: "ANY projectColours.partialLeft > 0")
} else if searchedText.lowercased() == "all" {
fetchRequest.predicate = NSPredicate(format: "ANY projectColours.fullLeft > 0 OR ANY projectColours.partialLeft > 0")
} else {
fetchRequest.predicate = NSPredicate(format: "name contains[cd] %@", searchedText)
}
}
发送8个字节,因此您需要再发送2个字节。第二次,您还发送8个字节(可能超出范围)。然后,buf_size
将为-6,与buf_size
相同。
简单的解决方法是发送to_send
(如果较小):
send
此外,如果to_send
不成功,则返回SIZE_MAX - 5
。将其分配给to_send
时,它与sent = send(socket, sbuf, to_send < buf_size ? to_send : buf_size, 0);
相同。您将需要一些错误处理才能解决此问题。
答案 1 :(得分:0)
我认为在发送的大文件上等于size_t的最大值 我有缓冲区溢出。
由于sent
的值作为send()
的返回值,并且send()
返回ssize_t
,这是一个有符号类型,不可能比{{1}宽},实际上可以肯定的是,size_t
通过返回-1表示错误。在这种情况下,还将send()
设置为指示错误的值。在我接触过的任何系统上,它都无法返回errno
的最大值。
如何防止这种情况?
首先,在担心预防之前,您应确保通过
检测
size_t
声明为sent
以匹配ssize_t
而不是send()
的返回类型,并且size_t
的值。第二,如果您处理文件的时间实际上比sent
所能代表的时间更长(更不用说ssize_t
了),那么在发送之前将整个内容加载到内存中是一个糟糕的主意任何一个。取而代之的是,将其装入(很多)较小的块中,然后一次发送一个这样的块中的数据。这不仅会降低感知延迟,而且还可以避免与接近所涉及数据类型的限制相关的任何风险。
此外,在执行此操作时,请注意正确执行操作。您可以很好地将size_t
调用包装在循环中以解决简短写入问题,但是正如@Artyer在他的答案中所描述的那样,您并没有完全正确,因为您没有减少尝试的字节数发送第二个及以后的电话。
什么是 读取文件并将其发送回的最佳实践?
如上所述。