2017-08-01 73 views
0

我需要字节插座传输的音频文件的字节和在接收端我需要妥善安排。例如,有两个音频文件A和B,I必须从A和传送读一个字节,接下来我要读从B和传输第一字节,从A这样转印有然后第二个字节和第二字节从乙做直至EOF,在接收器侧予必须组织为A和B.音频文件传输字节

上述一个I在C++(QT)在TCP套接字试图为一个音频文件正确接收字节。

QString path = "a4.wav"; 
QFile inputFile(path); 
inputFile.open(QIODevice::ReadOnly); 

QByteArray block; 
QDataStream out(&block, QIODevice::WriteOnly); 
out.setVersion(QDataStream::Qt_5_4); 

QByteArray q = inputFile.readAll(); 
block.append(q); 
inputFile.close(); 

out.device()->seek(0); 

qint32 x = 0; 
unsigned int i = 0; 
while (x < block.size()) { 
    qint32 y = socket->write(&block.data()[i],1); //Filling one byte in socket to write 
    x += y; 
    //qDebug() << y; 
    //qDebug() << x; // summary size you send, so you can check recieved and replied sizes 
    i++; 
} 

但这里在上面的代码中,我填充和写一个字节,但接收机侧我得到一串字节(例如接收14000bytes)。看起来写入插槽中的缓冲区填满了最大值,然后只有传输正在发生。我必须做什么,一次只写一个字节?

+0

为什么你把文件读入字节数组●然后复制它阻止?你为什么打开DataStream'out'? –

+0

没有人做每包TCP一个字节。 TCP是一个流,所以网络设备可以根据需要进行分片和粘贴。可以使用UDP,但仍然浪费,因为对于每个字节,您还会发送长度为20到40个字节的数据包标头。 – Velkan

回答

2

你不应该被字节逻辑做I O基于/的字节,它是没有效率。它也可能启用所谓的Nagle算法,它将在发送数据包之前等待更多的数据。我推荐在发送端:

QByte * p = buffer.data(); 
int sizeLeft = static_cast<int>(buffer.size()); 
while (sizeLeft > 0) { 
     int n = socket.send(p, sizeLeft); 
     if (n < 0) { 
      // Error 
      return false; // or throw exception 
     } 
     p += n; 
     sizeLeft -= n; 
} 

在接收大小你应该有一个体面的缓冲区,所以你可以做同样的缓冲。这个例子是性病载体,但它可能适用于Qt容器以及

int appendReceived(QSocket &socket, std::vector<std::uint32_t> buffer, int maxRecvLength) { 
    size_t prevSize = buffer.size(); 
    buffer.resize(prevSize + maxRecvLength); 
    int n = socket.recv(buffer.data() + prevSize, maxRecvLength); 
    if (n < 0) { 
     // Error 
     return n; // or throw exception 
    } 
    buffer.resize(prevSize + n); 
} 

你可以开始写数据之前可能做对发送方的安排。

std::vector<std::uint8_t> mergeVectors(const std::vector<std::uint8_t> &a, const std::vector<std::uint8_t> &b) { 
    std::vector<std::uint8_t> result; 
    result.reserve(a.size() + b.size())); 
    size_t minSize = std::min(a.size(), b.size()); 
    for(size_t i = 0; i < minSize; ++i) { 
     result.push_back(a[i]); 
     result.push_back(b[i]); 
    } 
    for (size_t i = minSize; i < a.size(); ++i) { 
     result.push_back(a[i]); 
    } 
    for (size_t i = minSize; i < b.size(); ++i) { 
     result.push_back(b[i]); 
    } 
    return result; 
} 

在接收端,你可能有:

void splitAndRemoveFront(std::vector<std::uint8_t> &buffer, std::vector<std::uint8_t> &a, std::vector<std::uint8_t> &b, size_t asize, size_t bsize) { 
    assert(buffer.size() >= asize + bsize); 
    size_t minSize = std::min(asize, bsize); 
    a.reserve(a.size() + asize); 
    b.reserve(b.size() + bsize); 
    auto p = buffer.begin(); 
    for(size_t i = 0; i < minSize; ++i) { 
     a.push_back(*p++); 
     b.push_back(*p++); 
    } 
    for (size_t i = minSize; i < asize; ++i) { 
     a.push_back(*p++); 
    } 
    for (size_t i = minSize; i < bsize; ++i) { 
     b.push_back(*p++); 
    } 
    buffer.erase(buffer.begin(), p); 
} 

当然,你也将需要以某种方式传输文件的大小,但你得到的基本思路。

+0

好的编码器:) :) –