我对下面的代码有一些问题。它旨在从服务器接收文件。只要服务器在发送后断开连接,它就可以 100% 正常工作。
如果服务器没有断开连接,则客户端的传输没有完成,客户端继续等待字节并且没有正确地跳出循环(当 fr_block_sz == 0 时),就像在服务器时一样收到文件后断开连接。它无休止地坐在循环中。
我希望能够接收文件并在之后保持连接打开。有什么建议吗?谢谢。
编辑:根据 Casey 的建议,我现在正在监视通过下面注释的代码写入的字节数,但出现了导致文件传输无法正确完成的奇怪行为。任何人都可以在我的代码中看到任何错误吗?谢谢。
编辑 2:我已经发布了关于我的问题的调试信息,以使其更清楚。
// Reciever of file (client)
int TotalSize = 7374; // hardcoded file size to expect
int FileSize = 0; // counter
int fr_block_sz = 0;
while ((fr_block_sz = recv(sd, revbuf, 1, 0)) > 0) //LENGTH == 512
{
if (fr_block_sz < 0)
if (errno == EAGAIN)
continue;
else
printf("File write failed");
if (fr_block_sz == 0)
break; //done
// edit based on comment - does not change behavior
if(FilzeSize > TotalSize)
{
fr_block_sz = fr_block_sz - (FileSize - TotalSize);
}
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
// add total bytes recvd every loop
FileSize += write_sz;
// if bytes recieved equals expect file size, break
if (FileSize >= TotalSize)// this is where my problem is, as sometimes
// FileSize == 7376 or 7672 instead of 7374
// When it fails, fr_block_sz == 24 which
// i don't think is right either. Even when
// set to break if FileSize > TotalSize, the
// loop still doesn't complete
break;
printf("Recieved size == %i of %i \n", FilzeSize, TotalSize);
if (write_sz < fr_block_sz)
{
printf("File write failed");
}
bzero(revbuf, 1);
}
printf("Transfer complete \n");
控制台输出:
Recieved size == 512 of 7374
Recieved size == 1024 of 7374
Recieved size == 1368 of 7374
Recieved size == 1880 of 7374
Recieved size == 2392 of 7374
Recieved size == 2736 of 7374
Recieved size == 3248 of 7374
Recieved size == 3760 of 7374
Recieved size == 4104 of 7374
Recieved size == 4616 of 7374
Recieved size == 5128 of 7374
Recieved size == 5472 of 7374
Recieved size == 5984 of 7374
Recieved size == 6496 of 7374
Recieved size == 6840 of 7374
Recieved size == 7352 of 7374
Recieved size == 7376 of 7374
一旦它到达这里,客户端将永远在循环中等待,并且没有任何反应。然后我必须从控制台手动停止程序,在程序停止后,只写入了 4096 字节的文件。如果有人能阐明我的问题,或者用“正常”的方式来解决这个问题,我将不胜感激。谢谢你。
编辑 - 固定(有点)。我找到了一种让它每次都能 100% 可靠工作的方法,那就是通过更改 LENGTH == 1,因此设置一个字节的缓冲区大小,如果内核正在逐字节写入,则无法获得短/长读取. 这可行,但显然不是最快的解决方案。我仍然想听听其他人的意见,并感谢您对 Rajal 的帮助。