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