Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 部分发送/接收TCP套接字c++;_C++_Sockets_Networking_Tcp - Fatal编程技术网

C++ 部分发送/接收TCP套接字c++;

C++ 部分发送/接收TCP套接字c++;,c++,sockets,networking,tcp,C++,Sockets,Networking,Tcp,我正在努力与TCP网络,特别是与部分发送和接收。我在看书 Beej的sockets教程和我正在尝试实现他在“数据封装”一段中提到的东西,创建不受部分发送/接收攻击的通信代码。我有一个函数,只要整个数据包都被发送,它就会在循环中发送,现在我正在处理接收部分。每次发送内容时,我首先创建一个包,其中包含包长度、源地址、目标地址和消息本身。这些字段使用诸如“$”或“/”等特殊字符相互分隔。看起来是这样的: $packet_length/source_addr%dest_addr<message&g

我正在努力与TCP网络,特别是与部分发送和接收。我在看书 Beej的sockets教程和我正在尝试实现他在“数据封装”一段中提到的东西,创建不受部分发送/接收攻击的通信代码。我有一个函数,只要整个数据包都被发送,它就会在循环中发送,现在我正在处理接收部分。每次发送内容时,我首先创建一个包,其中包含包长度、源地址、目标地址和消息本身。这些字段使用诸如“$”或“/”等特殊字符相互分隔。看起来是这样的:

$packet_length/source_addr%dest_addr<message>
接收函数:

int recieveall(int socket){

int n;

 n = recv( socket, buf, sizeof(buf), 0 );  // recieves message

    string packet(buf);

// searching for the packet length which is placed beetween $ and /

    int dollar_sign = packet.find("$");
    int slash = packet.find("/");

    buf_temp[0] = '\0';
    string packet_len = packet.substr(dollar_sign+1, slash-(dollar_sign+1) );

// checking if recieved full packet or a part of it -> comparing bufer length with packet size
// if not calls recieve in a loop untill gets the whole packet

    while(strlen(buf) < stoi(packet_len)){


        int total = strlen(buf);
        int left = stoi(packet_len)-total;

        n = recv( socket, buf_temp, left, 0 );

        left -= n;
        total +=n;

        if(total = stoi(packet_len)) {break;}

    }

    if(buf_temp[0] != '\0'){strcat(buf, buf_temp);} // concat 2 buffers to get the whole message


    if(n == 0){return n = 0;}
    if(n == -1){return n =-1;}
    if(n > 0){return n ;}


}
int receiveAll(int套接字){
int n;
n=recv(socket,buf,sizeof(buf),0);//接收消息
字符串包(buf);
//搜索放置在$and之间的数据包长度/
int-dollar\u-sign=packet.find($);
int slash=packet.find(“/”);
温度[0]='\0';
string packet_len=packet.substr(美元符号+1,斜杠-(美元符号+1));
//检查是否接收到完整数据包或部分数据包->比较bufer长度和数据包大小
//如果不是,则在循环中调用receive,直到获取整个数据包
while(strlen(buf)0){返回n;}
}
如果这很重要,则在accept循环中调用
receiveall()
,我也使用select()。我将感谢任何帮助或建议。

  • 您不应该假设缓冲区曾经以null结尾
  • 您应该保持到目前为止接收到的字节总数,并在到达时停止读取
  • 您应该为-1(错误)和零(流结束)测试
    recv()
    的返回值,并在每种情况下采取适当的(不同的)操作
      • 您不应该假设缓冲区曾经以null结尾
      • 您应该保持到目前为止接收到的字节总数,并在到达时停止读取
      • 您应该为-1(错误)和零(流结束)测试
        recv()
        的返回值,并在每种情况下采取适当的(不同的)操作

      谢谢您的关心,1。我删除了以缓冲区null结尾的if语句;2.我把它加起来等于已经接收到的字节数,每次修改某个内容时,我都用n来增加它。还更正了在循环(=相反=)3时中断的条件。错误处理将在稍后完成。经过所有的修正,我仍然收到比我发送的更多。也许我的测试错了。我将sendall()中的一行更改为仅发送10个字节:n=send(s,buf+total,10,0);我发送的内容:$32/0.0.0.0%0.0。我收到的是$32/0.0.0.0%0.0.+6字节的垃圾(一些字符)@Boman,ATM,你上面的代码中有太多的坏代码,不能做太多。修复EJP上面发布的所有问题实例。然后重新生成、重新测试、重新调试、重新测试等。如果仍然存在无法解决的问题,请将新代码附加到此问题,在旧代码的下面,或提出新问题。@Boman(1)的内容不仅仅是
      if
      语句。您正在循环
      ,而strlen(…)…)
      。在收到最后的尾随null之前,这永远不会起作用,如果您事先知道消息长度,那么您不应该也不必假设会有尾随null。(2) 描述你认为你的代码做什么是毫无意义的。它不起作用,这就是为什么你要发布这个问题。(3) “错误处理”现在在您调试程序时完成“以后再做错误处理”完全是胡说八道。谢谢你的关心,1。我删除了以缓冲区null结尾的if语句;2.我把它加起来等于已经接收到的字节数,每次修改某个内容时,我都用n来增加它。还更正了在循环(=相反=)3时中断的条件。错误处理将在稍后完成。经过所有的修正,我仍然收到比我发送的更多。也许我的测试错了。我将sendall()中的一行更改为仅发送10个字节:n=send(s,buf+total,10,0);我发送的内容:$32/0.0.0.0%0.0。我收到的是$32/0.0.0.0%0.0.+6字节的垃圾(一些字符)@Boman,ATM,你上面的代码中有太多的坏代码,不能做太多。修复EJP上面发布的所有问题实例。然后重新生成、重新测试、重新调试、重新测试等。如果仍然存在无法解决的问题,请将新代码附加到此问题,在旧代码的下面,或提出新问题。@Boman(1)的内容不仅仅是
      if
      语句。您正在循环
      ,而strlen(…)…)
      。在收到最后的尾随null之前,这永远不会起作用,如果您事先知道消息长度,那么您不应该也不必假设会有尾随null。(2) 描述你认为你的代码做什么是毫无意义的。它不起作用,这就是为什么你要发布这个问题。(3) “错误处理”现在在您调试程序时完成“错误处理在以后完成”完全是胡说八道。在流中处理消息的一个好方法是使用。(有关状态机图的示例,请参见的第23页。)从空缓冲区开始。一旦有足够的字节来包含消息长度,就可以从缓冲区中提取它。我通常从
      MessageLength
      (16位)、
      MessageType
      (8位)和
      MessageSubType
      (8位)的二进制值开始,而不是从文本开始,这样我就知道完整的消息头始终包含在4个字节中。在流中处理消息的一个好方法是使用。(有关状态机图的示例,请参见的第23页。)从空缓冲区开始。一旦你
      int recieveall(int socket){
      
      int n;
      
       n = recv( socket, buf, sizeof(buf), 0 );  // recieves message
      
          string packet(buf);
      
      // searching for the packet length which is placed beetween $ and /
      
          int dollar_sign = packet.find("$");
          int slash = packet.find("/");
      
          buf_temp[0] = '\0';
          string packet_len = packet.substr(dollar_sign+1, slash-(dollar_sign+1) );
      
      // checking if recieved full packet or a part of it -> comparing bufer length with packet size
      // if not calls recieve in a loop untill gets the whole packet
      
          while(strlen(buf) < stoi(packet_len)){
      
      
              int total = strlen(buf);
              int left = stoi(packet_len)-total;
      
              n = recv( socket, buf_temp, left, 0 );
      
              left -= n;
              total +=n;
      
              if(total = stoi(packet_len)) {break;}
      
          }
      
          if(buf_temp[0] != '\0'){strcat(buf, buf_temp);} // concat 2 buffers to get the whole message
      
      
          if(n == 0){return n = 0;}
          if(n == -1){return n =-1;}
          if(n > 0){return n ;}
      
      
      }