我在使用下面的代码时遇到了一些问题。它旨在从服务器接收文件。只要服务器在发送后断开连接,它就可以100%正常工作。
如果服务器没有断开连接,那么传输不会完成客户端,并且客户端继续等待字节并且不会正确地突破循环(当fr_block_sz == 0时),因为它确实当服务器在收到文件后断开连接。它无休止地坐在循环中。
我希望能够接收文件并在之后保持连接打开。有什么建议?感谢。
编辑:Per 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");
CONSOLE OUTPUT:
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。
答案 0 :(得分:1)
您的问题是,如果服务器没有关闭连接,您的客户端不知道文件传输何时完成。你怎么能传达这个事实?
答案 1 :(得分:1)
我建议在客户端和服务器之间遵循一些协议。我可以在下面展示一个例子。
可以有其他方式接收文件,我们有时会在下载管理器中看到。比如打破块中的文件或使用相同的连接接收多个文件,但我相信一旦你设置了协议,就可以轻松搞清楚增强功能。
希望它有所帮助。
伪
只丢弃超过文件大小的任何字节。在fwrite之前尝试以下。
if(FilzeSize > TotalSize)
{
fr_block_sz = fr_block_sz - (FilezeSize - TotalSize);
}
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
它应该写出不包括最后2个字节的revbuf。
此致 Kajal