如何在udpc++中发送和接收大量数据

How to send and receive large amounts of data in udp c++

本文关键字:数据 udpc++      更新时间:2023-10-16

我正试图用以下代码在udp c++中同时发送和接收大量数据。我一次只能发送16000个比特,字符。如何在不关闭套接字的情况下发送/接收数百万字节的数据?

//sends the data contained in aliceBuf, which is, char of size 16000. 
if (sendto(aliceSocket, aliceBuf, strlen(aliceBuf), 0, (struct sockaddr *)&bobAddr, sizeof (bobAddr)) == -1) {
    perror("sendto");
    exit(1);
}

// receiver code: it is receiving just 16000 char.
recvlen = recvfrom(aliceSocket, aliceBuf1, receiveBuffer, 0, (struct  sockaddr*)&bobAddr,  &bobAddrSize);
if (recvlen >= 0) {
    aliceBuf1[recvlen] = 0; /* expect a printable string - terminate it */
}

您可以一次性发送大量数据,但您必须问自己的问题是:接收方如何知道需要多少数据?

我通常通过在数据前面加上长度来显式地编码长度,然后接收器循环直到数据量到达,或者通过使用某种数据结束标记,如"C"字符串,或者更隐含地如json数据,接收器循环在数据本身中寻找东西来处理这些情况。

您必须在UDP之上添加一个协议,就像使用TCP一样。很抱歉你不得不做一些工作,但事情就是这样。有些数据报可能会丢失,所以您可能也必须为此添加一层。1M比特是最大UDP数据报的两倍,所以即使你重新配置网络堆栈以允许更大的数据报,你仍然会达到64k的限制,因此需要一个协议。

我做了这样的循环:

   int totalGoLength= no of blocks you want to send 
   int dataLengthOneGo = length of data in one block you want to send
  //start loop
    int iii=1 ;
    while (iii <= totalGoLength){ //send by dividing into packets
////--SEND/by converting to char * for less memory occupation----
// theString has the string  data to send
    std::string part(theString.substr(0, dataLengthOneGo)); 
     char * s4;
     s4 = new char[part.size() + 1];
     memcpy(s4, part.c_str(), part.size() + 1);
    if (sendto(aliceSocket, s4, strlen(s4), 0, (struct sockaddr *)&bobAddr, sizeof (bobAddr)) == -1) {
        perror("sendto");
        exit(1);
    }
        delete [] s4;
        ////----------------------Receiving------------
    // receive buffer should have sufficient memory allocation
          char *aliceBuf1;
      aliceBuf1 = new char[receiveBuffer];
      recvlen = recvfrom(aliceSocket, aliceBuf1, receiveBuffer, 0, (struct sockaddr *)&bobAddr, &bobAddrSize);
    if (recvlen >= 0) {
        aliceBuf1[recvlen] = 0; /* expect a printable string - terminate it */
        //convert char to string
        string s1(aliceBuf1);
        //erase the white space
        s1.erase(remove_if(s1.begin(), s1.end(), isspace), s1.end());
        //convert string into integer vector
        std::vector<int> ints;
        ints.reserve(s1.size());
        std::transform(std::begin(s1), std::end(s1), std::back_inserter(ints), [](char c) {
            return c - '0'; });
    }
    delete[] aliceBuf1;
    justCopy=ints;
    KeepData.insert(KeepData.end(),justCopy .begin(), justCopy.end());
    justCopy.erase(justCopy.begin(), justCopy.end()); //erase for next time
    ints.erase(ints.begin(), ints.end()); //erase for next time
    theString.erase(theString.begin(), theString.begin() + dataLengthOneGo);//keep the remaining
    iii=iii+1;
}//end of the while