在 C 中通过套接字发送 mp3 文件

Posted

技术标签:

【中文标题】在 C 中通过套接字发送 mp3 文件【英文标题】:Send mp3 file over socket in C 【发布时间】:2015-06-01 20:15:53 【问题描述】:

我在尝试通过套接字发送 mp3 文件时遇到问题

这是我用来读取 mp3 文件的代码

FILE *file;
char *audio;
unsigned long fileLen;

file = fopen("AAAA.mp3", "rb");
if (!file)

    fprintf(stderr, "Unable to open file");
    return;


fseek(file, 0, SEEK_END);
fileLen = ftell(file);
fseek(file, 0, SEEK_SET);

audio = (char *)malloc(fileLen+1);
if (!audio)

    fprintf(stderr, "Memory error!");
    fclose(file);
    return;


fread(audio, fileLen, 1, file);
fclose(file);

然后我有这个功能来发送内容

int send_message(int sockfd, uint16_t code, char *message)

    int bytes_sent;
    uint16_t l_msg;
    uint16_t l_msg_net;
    char buffer[BUFFER_SIZE+CODE_LEN+MSG_LEN];

    l_msg = strlen(message) + 1;
    l_msg_net = htons(l_msg);

    code = htons(code);

    // Save message code
    memcpy(buffer, &code, CODE_LEN);
    // Save message length
    memcpy(buffer + CODE_LEN, &l_msg_net, MSG_LEN);
    // Save message
    memcpy(buffer + CODE_LEN + MSG_LEN, message, l_msg);

    bytes_sent = send(sockfd, buffer, (l_msg + CODE_LEN + MSG_LEN), 0);

    return(bytes_sent);

如果我在发送之前将缓冲区(第一段代码中的audio var)保存到文件中,效果很好,但是当我尝试将其保存在服务器端时,它会损坏。还有,缓冲区的内容是这个??$?

不知道为什么,我想是因为是二进制文件。

有什么想法吗?也许我以错误的方式发送数据?

提前致谢

【问题讨论】:

嗯,它里面有strlen(),所以它不是很好。使用 strlen() 调用的所有网络/套接字代码中有 99% 是 borken。 @MartinJames 100% 假设二进制流。 我用 sizeof(message) 试过了,但结果是一样的... 你真的应该阅读一些文档。真的。 sizeof指针是指针的大小。 【参考方案1】:

这是一个二进制文件,意味着包含'\0'的字节是合法数据。

这一行:

fileLen = ftell(file);

告诉你要发送多少字节。

另外,send() 返回 ssize_t,而不是 int。根据man page:

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

更好的是,直接使用sendfile()发送文件:

struct stat sb;
int fd = open( "AAAA.mp3", O_RDONLY );
fstat( fd, &sb );
// first send the file size - NB this is not correct as it
// assumes sizeof( sb.st_size ) is the same on the other 
// end *and* has the same endianness
write( sockfd, &sb.st_size, sizeof( sb.st_size ) );
ssize_t bytesSent = sendfile( sockfd, fd, NULL, sb.st_size );

【讨论】:

那么,除了使用 sendfile 之外,没有其他方法可以发送文件吗?问题是我不明白为什么数据在另一端被损坏。看来我无法将缓冲区作为“字符串”发送 @Ernes - 您不能将其作为字符串发送,因为它不是字符串。如果您想编写代码,有很多方法可以通过套接字发送文件。它们几乎都包括编写多行代码以将数据复制到用户空间,然后将其写入套接字。 sendfile() 使用一行代码发送数据,直接发送数据,无需在读取数据时将数据复制到用户空间,然后在将数据写入套接字时返回。

以上是关于在 C 中通过套接字发送 mp3 文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中通过套接字发送大量数据的正确方法是啥?

在 C++ 中通过套接字发送图像

python 在python中通过套接字发送消息

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

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

在 c++ 中通过套接字(发送函数)发送图片,但不接收完整(Windows)!