简体   繁体   English

C ++如何在Winsock中正确接收文件?

[英]C++ How to properly receive a file in Winsock?

I'm working on a CHAT Program in C++. 我正在使用C ++编写CHAT程序。 And stuck upon a problem of sending/receiving file. 并停留在发送/接收文件的问题上。 My server side is Python that runs in background of Flask App accepting TCP Connections and forwarding incoming/outgoing data to chat clients. 我的服务器端是在Flask App的后台运行的Python,它接受TCP连接并将传入/传出的数据转发到聊天客户端。 It has no problem and works great. 它没有问题,效果很好。 My problem is on the client receiving. 我的问题是客户收到的。 I added this feature of Sending and receiving file. 我添加了发送和接收文件的功能。 While send goes out fine with no error (Tested and it works). 虽然发送正常,没有错误(经过测试,可以正常工作)。 Receiving on the client side has gave me a headache. 在客户端接收消息使我头疼。

I'm using the following to receive the file whether it is binary or Text. 我正在使用以下内容来接收文件,无论它是二进制文件还是文本文件。

// 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");
}

This works but the data is not written in the file fully. 这可行,但是数据没有完全写入文件中。 For Example; 例如; If I send a 144 kb File it will be saved on the other side as 142 kb. 如果我发送144 kb的文件,它将另存为142 kb。 And the program just stops there. 程序就在那里停止。

Final Question; 最后问题; How do I receive a large/small file in C++? 如何使用C ++接收大/小文件?

EDIT : After @Algirdas Preidžius Response, I retested it. 编辑:@AlgirdasPreidžius响应后,我重新测试了它。 Here are some screenshots of the file before and after sent. 这是发送前后文件的一些屏幕截图。

This is before it's sent. 这是在发送之前。

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

This is after it's sent. 这是在发送之后。 https://www.upload.ee/image/10164544/wsa.PNG https://www.upload.ee/image/10164544/wsa.PNG

There are 3 ways you can handle this situation. 您可以通过3种方式处理这种情况。

  • Message delimiters/line terminator 消息定界符/行终止符
  • Inserting the size of the message before the message 在消息之前插入消息的大小
  • Use non-blocking IO in conjunction with select 将非阻塞IO与select结合使用

Here is a quick example of parsing the incoming message looking for a line terminator. 这是解析传入消息以寻找行终止符的快速示例。 For example: 例如:

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");

Note that this is a quick untested example showing you how you might parse an incoming message. 请注意,这是一个未经测试的快速示例,向您显示了如何解析传入的消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM