QTCPSocket中逐字节传输音频文件(Qt-C ++)

时间:2017-08-01 04:47:16

标签: c++ qt byte transfer qtcpsocket

我需要在socket和接收器端逐字节传输音频文件我需要正确安排它。例如,有两个音频文件A和B,我必须从A读取一个字节并传输,接下来我必须从B读取第一个字节并传输,然后从A读取第二个字节,从B读取第二个字节,这样转移已经要做到EOF,在接收方,我必须为A和B组织正确接收的字节。

上面我在TCP套接字中用C ++(Qt)尝试过一个音频文件。

fine_id

但是在上面的代码中,我正在填写并写入一个字节,但是接收方我正在获得一堆字节(例如接收14000字节)。似乎写入套接字中的缓冲区填充最大,然后才发生传输。我必须做什么,一次只写一个字节?

1 个答案:

答案 0 :(得分: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;
 }

在接收大小上你应该有一个不错的缓冲区,所以你可以做同样的缓冲。示例使用std向量,但它也可以应用于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);
}

当然,你还需要以某种方式传输文件的大小,但你会得到基本的想法。