【问题标题】:C++ How to properly receive a file in Winsock?C++ 如何在 Winsock 中正确接收文件?
【发布时间】:2019-11-13 05:37:45
【问题描述】:

我正在使用 C++ 编写一个聊天程序。并陷入发送/接收文件的问题。我的服务器端是 Python,它在 Flask App 的后台运行,接受 TCP 连接并将传入/传出数据转发到聊天客户端。它没有问题并且效果很好。我的问题出在客户端接收上。我添加了发送和接收文件的这个功能。虽然发送正常且没有错误(经过测试并且可以正常工作)。在客户端接收让我很头疼。

我正在使用以下内容来接收文件,无论是二进制文件还是文本文件。

// filebuf is defined as
// char filebuf[BUFFER];
// BUFFER is 1024.
void CHAT::recvFile()
{
 int fsize;
 std::ofstream recvfile(filename, std::ios::app, std::ios::binary);
 while ((fsize = recv(sockfd, filebuf, sizeof(filebuf), 0)) > 0)
 {
     recvfile.write(filebuf, sizeof(filebuf));
 }
 recvfile.close();
 respond("Received file.\n");
}

这可行,但数据未完全写入文件中。例如;如果我发送一个 144 kb 的文件,它将在另一侧保存为 142 kb。程序就停在那里。

最后一个问题;如何在 C++ 中接收大/小文件?

编辑:在@Algirdas Preidžius Response 之后,我重新测试了它。以下是文件发送前后的部分截图。

这是在发送之前。

https://www.upload.ee/image/10164543/ook.PNG

这是在发送之后。 https://www.upload.ee/image/10164544/wsa.PNG

【问题讨论】:

  • 这是一个错字:std::ofstream recvfile(filename, std::ios::app, std::ios::binary);?不应该是std::ofstream recvfile(filename, std::ios::app | std::ios::binary);吗?
  • 天哪!是的,那是一个错字。感谢您指出这一点!
  • 发送文件后让服务器关闭连接。这应该会导致 recv 函数在客户端上退出。
  • @WBuck 没有别的办法吗?我不能只是关闭连接。
  • 您需要以某种方式指示数据的结尾,例如发送数据前的长度并倒计时,或关闭/关闭远端。

标签: c++ windows networking winsock winsock2


【解决方案1】:

有 3 种方法可以处理这种情况。

  • 消息分隔符/行终止符
  • 在消息前插入消息的大小
  • 结合select使用非阻塞IO

这是一个解析传入消息以查找行终止符的快速示例。 例如:

int fsize;
std::string filebuf( '0', 1024 );

while ( ( fsize = recv( sockfd, filebuf.data( ), filebuf.size( ), 0 ) ) > 0 )
{
     if( std::size_t index{ filebuf.find( "#end", 0 ) }; 
          index != std::string::npos )
     {
         // The line terminator was found so don't call the
         // the receive function again as there should be nothing
         // remaining in the stream to read.
     }
     /*Write the data to your file.*/
     filebuf.clear( );
}
respond("Received file.\n");

请注意,这是一个未经测试的快速示例,向您展示如何解析传入消息。

【讨论】:

  • Bucky,我想我通过添加超时来修复它。现在可以了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
相关资源
最近更新 更多