我在下面的代码中遇到了一些问题。它旨在从服务器接收文件。只要服务器在发送后断开连接,它就可以100%正常工作。如果服务器断开,文件传输才会完成
如果服务器没有断开连接,那么传输不会完成客户端,并且客户端继续等待字节并且不会正确地跳出循环(当fr_block_sz == 0时),因为它服务器在收到文件后断开连接。它无休止地坐在循环中。
我希望能够接收文件并保持连接打开后。有什么建议?谢谢。
编辑:根据凯西的建议我现在正在监视通过下面的注释代码写入的字节数量,但得到奇怪的行为导致文件传输未正确完成。任何人都可以在我的代码中看到任何错误吗?谢谢。
编辑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,因此设置一个字节的缓冲区大小,并且如果内核正在为字节写入字节,则无法获得短/长读取。这可行,但显然不是最快的解决方案。我仍然希望听到其他人的声音,并感谢你的帮助拉贾尔。
2013-07-15
4r4r4r
+0
所以,你必须看看服务器代码,而不是 –
+0
无关:填充用零的缓冲器你与其他数据填充它之前,是没有意义的。 –
+0
凯西 - 固定,bbonev - 模糊评论,跟进。 –