如何使用套接字传输 pdf、mp3 或 mp4 文件?

Posted

技术标签:

【中文标题】如何使用套接字传输 pdf、mp3 或 mp4 文件?【英文标题】:how to transfer pdf, mp3 or mp4 files using socket? 【发布时间】:2014-11-10 17:43:55 【问题描述】:

我制作了一个客户端服务器应用程序,其中客户端发送文件(即 ODT、PDF、MP3、MP4 等),服务器接收文件。

我将文件分成块,然后在 while 循环中传输它们。 下面我给出了客户端和服务器的主要逻辑。

当我使用 127.0.0.1 进行环回时,此代码可以成功运行。

但是当我在两台不同的 PC 上运行客户端和服务器时,传输文件后客户端退出但服务器继续接收,然后我必须按 ctrl^C。即使客户端的文件大小只有 4.2 MB 左右,服务器端的文件大小也达到 1GB 以上。

在环回中我没有遇到这样的问题。

请告诉我需要的更正。

client.c

#define SIZE 512   // or anything else
char sendbuff[SIZE];
FILE *fr;
fr = fopen("1.mp3","r");
while(!feof(fr))
    count = fread(sendbuff, SIZE,1,fr);
    count = send(clientsd, sendbuff,SIZE,0);  //clientsd is socket descriptor. 

send(clientsd, "xyz", 3, 0);      //sending '1'. tells server, transmission is over now. 
close(fr);

服务器.c

#define SIZE 512   // same as client side
char recvbuff[SIZE];

FILE *fw;
fw = fopen("2.mp3","w");
while(1)
    count = recv(connsd, recvbuff, SIZE,0);

    if(!strcmp(recvbuff,"xyz"))
    break;

    fwrite(recvbuff,SIZE, 1, fw);
    memset(recvbuff,0,SIZE);

printf("Exit while\n");
fclose(fw);

还有其他简单有效的方法吗?

注意:我已经改变了我的问题。这里有一些答案是关于我传输“1”而不是“xyz”的旧问题。这是一个错误。

【问题讨论】:

if(recvbuff[0]=='1') break; ... 什么?为什么? @indiv 推测是由于服务器调用send(clientsd, "1", 1, 0); 来终止传输。不过,这似乎是一种检查文件结尾的糟糕方法。 客户端向服务器发送 1 告诉他现在我将不再传输任何数据,因此这表示传输结束。如果我们删除它,那将是无限循环 @AeroX 在此之前我尝试过 send(clientsd,"quit",4,0);并在服务器端 -> if(!strcmp(recvbuff,"quit")) break;但仍然有同样的问题。 如果您发送的文件恰好有字节 0x31 会发生什么?你不需要告诉客户你已经完成了。只需关闭套接字。或者发送文件的长度 first 以便接收者知道需要多少字节。此外,count = recv(...) 然后完全忽略count 并将SIZE 字节写入文件是没有意义的。也许您想对发送方和接收方保存的 count 值做一些事情,而不是忽略它们? 【参考方案1】:

最明显的问题是您在服务器端的停止条件。

您假设如果接收到的第一个字节是'1' (0x31) 则传输结束,但它可能是数据的一个字节(如果文件中块的第一个字节实际上是'1') .所以你需要一些其他的方式来表示文件的结束。一种可能性是对发送的每个数据包使用包装,例如,在每个数据包发送特定值(例如“1”)后跟长度之前,当传输完成时发送“0”表示传输完成完成。

我能看到的其他问题是:

    您以读取文本 ("r") 和写入文本 ("w") 的形式打开文件,如果 EOF 序列出现在文件中间,这将停止处理,而您需要以读取的方式打开它们/write binary(分别为“rb”/“wb”)。

    你使用 512 字节的块,如果文件不是 512 字节的倍数怎么办?

【讨论】:

以上是关于如何使用套接字传输 pdf、mp3 或 mp4 文件?的主要内容,如果未能解决你的问题,请参考以下文章

MP4的定义是啥?怎么区别MP4和视频MP3?

如何使用 Node.js 通过 ffmpeg 流式传输 MP4 文件?

在 Android 上使用 OpenSL ES 通过套接字通信流式传输 MP3 音频

如何将 .MP4 文件等本地文件流式传输到 Chrome Cast?

从 Android WebView 中的链接播放 MP4 或 MP3

如何使用 ffmpeg/php 在按钮单击时将 mp4 文件转换为 mp3?