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ファイルのヘッダーの一部になります。
TCPソケットに書き込むために.wavファイルの内容全体を正しく読み取るにはどうすればよいですか?
ありがとう。
それは簡単です:filesize
バイト単位のファイルのサイズです。ただし、sizeof(buffer)
32ビットOSでは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ヘッダーの解析を回避することをお勧めします。また、小さいバッファを割り当て、数回読み取って大きいファイルを送信することをお勧めします。
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;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加