如何在 C/C++ 中通过 TCP 发送 .mp4 文件?
How to send .mp4 file over TCP in C/C++?
我正尝试在 C++ 应用程序中通过 TCP client/server 发送文件。场景很简单;客户端发送文件,服务器端接收文件。我可以成功发送基于文本(例如 .cpp 或 .txt)的文件,但是当我尝试发送诸如 .mp4 或 .zip 的文件时,服务器上收到的文件已损坏。
client.cpp
FILE *fptr = fopen(m_fileName.c_str(), "rb");
off_t offset = 0;
int bytes = 1;
if(fptr){
while (bytes > 0){
bytes = sendfile(m_sock, fptr->_fileno, &offset, BUFFER_SIZE);
std::cout<< "sended bytes : "<< offset << '\n';
}
}
fclose(fptr);
std::cout<< "File transfer completed!\n";
Server.cpp
//some stuff...
for (;;) {
if ((m_result = recv(epes[i].data.fd, buf, BUFFER_SIZE, 0)) == -1) {
if (errno == EAGAIN)
break;
exit_sys("recv");
}
if (m_result > 0) {
buf[m_result] = '[=12=]';
std::ofstream outfile;
if(!outfile.is_open())
outfile.open(m_filename.c_str(), std::ios_base::app | std::ios_base::binary);
outfile << std::unitbuf << buf;
m_filesize -= m_result;
std::cout << "count : " << m_result << '\n';
std::cout << "remain data : " << m_filesize << '\n';
if(!m_filesize){
outfile.close();
m_fileTransferReady = 0;
std::cout<<"File transfer stop\n";
if (send(epes[i].data.fd, "transferok", 10, 0) == -1)
exit_sys("send");
}
}
//some stuff for else
}
我在发送和接收文件时使用了二进制模式,但我想这还不够。格式化文件有没有特殊的发送方式?
我按照G.M的方法找到了解决方案。评论中提到。在以二进制模式打开的文件末尾添加空字符会导致非基于文本的文件出现问题。另一个问题是 << 运算符的使用。需要使用notstream的write成员函数。结果;
server.cpp
//...
//...
if (m_result > 0) {
//buf[m_result] = '[=10=]'; //Deleted!
std::ofstream outfile;
if(!outfile.is_open())
outfile.open(m_filename.c_str(), std::ios_base::app | std::ios_base::binary);
outfile << std::unitbuf; //Modified
outfile.write(buf, m_result); //Added
m_filesize -= m_result;
//...
//...
我正尝试在 C++ 应用程序中通过 TCP client/server 发送文件。场景很简单;客户端发送文件,服务器端接收文件。我可以成功发送基于文本(例如 .cpp 或 .txt)的文件,但是当我尝试发送诸如 .mp4 或 .zip 的文件时,服务器上收到的文件已损坏。
client.cpp
FILE *fptr = fopen(m_fileName.c_str(), "rb");
off_t offset = 0;
int bytes = 1;
if(fptr){
while (bytes > 0){
bytes = sendfile(m_sock, fptr->_fileno, &offset, BUFFER_SIZE);
std::cout<< "sended bytes : "<< offset << '\n';
}
}
fclose(fptr);
std::cout<< "File transfer completed!\n";
Server.cpp
//some stuff...
for (;;) {
if ((m_result = recv(epes[i].data.fd, buf, BUFFER_SIZE, 0)) == -1) {
if (errno == EAGAIN)
break;
exit_sys("recv");
}
if (m_result > 0) {
buf[m_result] = '[=12=]';
std::ofstream outfile;
if(!outfile.is_open())
outfile.open(m_filename.c_str(), std::ios_base::app | std::ios_base::binary);
outfile << std::unitbuf << buf;
m_filesize -= m_result;
std::cout << "count : " << m_result << '\n';
std::cout << "remain data : " << m_filesize << '\n';
if(!m_filesize){
outfile.close();
m_fileTransferReady = 0;
std::cout<<"File transfer stop\n";
if (send(epes[i].data.fd, "transferok", 10, 0) == -1)
exit_sys("send");
}
}
//some stuff for else
}
我在发送和接收文件时使用了二进制模式,但我想这还不够。格式化文件有没有特殊的发送方式?
我按照G.M的方法找到了解决方案。评论中提到。在以二进制模式打开的文件末尾添加空字符会导致非基于文本的文件出现问题。另一个问题是 << 运算符的使用。需要使用notstream的write成员函数。结果;
server.cpp
//...
//...
if (m_result > 0) {
//buf[m_result] = '[=10=]'; //Deleted!
std::ofstream outfile;
if(!outfile.is_open())
outfile.open(m_filename.c_str(), std::ios_base::app | std::ios_base::binary);
outfile << std::unitbuf; //Modified
outfile.write(buf, m_result); //Added
m_filesize -= m_result;
//...
//...