gpt4 book ai didi

c++ - 如何使用 Linux 中的套接字层在 C++ 上编写 .wav 文件?

转载 作者:可可西里 更新时间:2023-11-01 02:35:14 25 4
gpt4 key购买 nike

我正在尝试通过套接字在 Linux 上通过 TCP 在 C++ 中发送 wav 文件,但我不明白如何正确读取 wav 文件。

我的目标是将客户端上的文件读入一个char数组,用“write()”发送给服务器,服务器应该再次将数据写入本地wav文件。

我是这样读取 .wav 文件的:

////////////define socket - left out for simplicity

ifstream file ("audio.wav", ios::in|ios::binary|ios::ate); //open .wav file
char * buffer; //declare data buffer, should contain .wav data to write to socket
streampos filesize; //size of file
int n; //number of written bytes

//if file opened correctly, read content and write to socket
if (file.is_open()){
filesize = file.tellg();
buffer = new char [filesize];
file.seekg (0, ios::beg);
file.read (buffer, filesize);
file.close();
n = write(socket, buffer, sizeof(buffer));
}

在服务器上,这将返回长度为“4”的数组“RIFF”,因此它是 wav 文件 header 的一部分。

如何正确读取整个 .wav 文件内容以写入 TCP 套接字?

谢谢。

最佳答案

这很简单:filesize 是以字节为单位的文件大小。但是,sizeof(buffer) 在 32 位操作系统上仅为 4。像这样修改您的代码:

if(file.is_open()) {
filesize = file.tellg();
buffer = new char [filesize];
file.seekg (0, ios::beg);
file.read (buffer, filesize);
file.close();
n = write_all(socket, buffer, filesize); // use filesize here
delete[] buffer; // !!
}

为了简化另一端的处理,您可能希望先发送 filesize 以避免解析 RIFF header 以了解要接受多少字节。我还建议分配一个较小的缓冲区并多次读取以发送较大的文件:

if(file.is_open()) {
filesize = file.tellg();
file.seekg(0, ios::beg);

uint32_t remains = filesize;
write(socket, &remains, sizeof(uint32_t));
// write 4B with size of the file (optional)

buffer = new char[(filesize > 4096)? 4096 : filesize];
// only up to 4k buffer to avoid running out of memory

n = 0;
while(remains > 0) {
int chunk = (remains > 4096)? 4096 : remains;
// decide how much to read in at one time (not more than size of the buffer)

file.read(buffer, chunk);
n += write_all(socket, buffer, chunk);
// read a chunk and write it to the socket

remains -= chunk;
// update number of bytes that remains to be transferred
}
// send the file several times

file.close();
delete[] buffer; // !!
}

您可能会注意到辅助函数 write_all 的使用。这是必需的,因为套接字可能已满,然后 write 将不会写入所有提供给它的数据。它可能看起来像这样:

size_t write_all(int socket, const char *buffer, size_t size)
{
size_t n = 0;
while(size > 0) {
size_t written = write(socket, buffer, size);
if(written == -1)
return written; // handle errors
n += written;
size -= written;
}
return n;
}

关于c++ - 如何使用 Linux 中的套接字层在 C++ 上编写 .wav 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23571325/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com