我正在使用 C++ 开发一个 CHAT 程序。并陷入发送/接收文件的问题。我的服务器端是 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 回复后,我重新测试了它。以下是文件发送前后的一些屏幕截图。
这是在发送之前。
最佳答案
有 3 种方法可以处理这种情况。
- 消息定界符/行终止符
- 在消息前插入消息的大小
- 将非阻塞 IO 与
select
结合使用
这是一个简单的示例,用于解析传入消息以查找行终止符。 例如:
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");
请注意,这是一个未经测试的快速示例,向您展示了如何解析传入消息。
关于C++ 如何在 Winsock 中正确接收文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56854717/