如何在 C/C++ 中通过 TCP 发送 .mp4 文件?

Posted

技术标签:

【中文标题】如何在 C/C++ 中通过 TCP 发送 .mp4 文件?【英文标题】:How to send .mp4 file over TCP in C/C++? 【发布时间】:2021-12-31 07:44:57 【问题描述】:

我正在尝试在 C++ 应用程序中通过 TCP 客户端/服务器发送文件。场景非常简单;客户端发送文件和服务器端接收文件。我可以成功发送基于文本(例如 .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] = '\0';
        
        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

我在发送和接收文件时使用二进制模式,但我想这还不够。格式化文件有特殊的发送方式吗?

【问题讨论】:

您的服务器代码将每个接收到的数据块视为一个以空字符结尾的字符数组。这对于可以合法包含空值的二进制数据无效。尝试改用unformatted output。 【参考方案1】:

我通过 G.M. 的方式找到了解决方案。评论中提到。在以二进制模式打开的文件末尾添加空字符会导致非基于文本的文件出现问题。另一个问题是使用

服务器.cpp

//...
//...
    
    if (m_result > 0) 
        //buf[m_result] = '\0';       //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/C++ 中通过 TCP 发送 .mp4 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在rails中通过tcp发送值?

在 Erlang 中通过 tcp 套接字发送元组

在java中通过TCP发送数据记录

在 C++ 中通过 tcp 套接字发送结构

在PHP中通过TCP发送XML EPP请求

在 Qt 中通过 TCP 传输大文件