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

时间:2014-09-16 12:10:08

标签: c++ visual-studio-2010 sockets visual-c++ udp

我正在尝试使用以下代码在udp c ++中一次发送和接收大量数据。我可以立即发送16000位,char。如何在不关闭套接字的情况下发送/接收数百万字节的数据?

//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 */
}

3 个答案:

答案 0 :(得分:1)

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

我通常通过以下方式处理这些情况:通过在数据前加上长度来显式编码长度,然后接收器循环直到数据量已经到达,或者通过某种类型的数据结束标记,如“C”字符串或更隐含地像json数据和接收器循环在数据本身中寻找某些东西。

答案 1 :(得分:0)

您必须在UDP之上添加协议,就像使用TCP一样。对不起,你必须做一些工作,但事情就是这样。某些数据报可能会丢失,因此您可能还需要添加一个图层。无论如何,1M位是最大可能的UDP数据报的两倍 - 所以即使您重新配置网络堆栈以允许更大的数据报,您仍然会达到64k限制,因此需要协议。

答案 2 :(得分:0)

我做了这样的循环:

   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