我正在尝试使用C ++中的GO和TCP服务器从TCP客户端发送Base64编码的图像。
这是C ++接收器的代码段
std::string recieve(int bufferSize=1024,const char *eom_flag = "<EOF>"){
char buffer[bufferSize];
std::string output;
int iResult;
char *eom;
do{
iResult = recv(client, buffer, sizeof(buffer), 0);
//If End OF MESSAGE flag is found.
eom = strstr(buffer,eom_flag);
//If socket is waiting , do dot append the json, keep on waiting.
if(iResult == 0){
continue;
}
output+=buffer;
//Erase null character, if exist.
output.erase(std::find(output.begin(), output.end(), '\0'), output.end());
//is socket connection is broken or end of message is reached.
}while(iResult > -1 and eom == NULL);
//Trim <EOF>
std::size_t eom_pos = output.rfind(eom_flag);
return output.substr(0,eom_pos);}
想法将一直接收到消息,直到找到消息结尾,此后继续侦听同一TCP连接上的另一条消息。
Golang TCP客户端代码段。
//Making connection
connection, _ := net.Dial("tcp", "localhost"+":"+PortNumber)
if _, err := fmt.Fprintf(connection, B64img+"<EOF>"); err != nil {
log.Println(err)
panic(err)
}
尝试的方法:
观察:
客户端发送的字符串的长度是固定的,而接收函数之后的字符串的长度较大且 随机。示例:转到客户端字符串的长度为25243。对于相同的字符串,当我收到时的长度 循环中的发送和接收运行是25243、26743、53092、41389、42849。
在将接收到的字符串保存到文件中时,我在字符串中看到<0x7f> <0x02>字符。
我正在将winsock2.h用于c ++套接字。
答案 0 :(得分:2)
您将接收到的数据视为C字符串-一个以0字节结尾的字节序列-不正确。
recv
接收一些字节并将其放入buffer
中。假设它收到了200个字节。
然后您执行strstr(buffer,eom_flag);
。 strstr
不知道收到了200个字节。 strstr
从缓冲区的开头开始,一直寻找直到找到或0字节为止。即使您没有收到一个,它也有可能在缓冲区的其他824字节中找到一个。
然后您执行output += buffer;
。这也将缓冲区视为以0字节结尾。这将遍历整个缓冲区(而不仅仅是前200个字节)以找到0字节。然后它将把到目前为止的所有内容添加到output
中。同样,它可能会在缓冲区的最后824个字节中找到一个0字节,并添加太多数据。它可能根本不会在缓冲区中找到0字节,然后它将继续添加来自其他变量的额外数据,这些变量存储在内存中buffer
旁边。或者,它可能会在前200个字节中找到一个0字节,然后在此停止(但前提是您发送了0个字节)。
您应该做的是注意收到的字节数(即iResult
),并将该字节数添加到输出中。您可以使用:
output.insert(output.end(), buffer, buffer+iResult);
(正如Phillipe Thomassigny在评论中指出的那样),可能不会一次全部收到“”。您可能会分别收到“”。您应该检查output
是否具有“”,而不是检查buffer
是否具有“”。 (这对性能的影响留给读者练习)
顺便说一下,此行目前不执行任何操作:
output.erase(std::find(output.begin(), output.end(), '\0'), output.end());
因为永远不会将'\ 0'添加到output
,因为对于output += buffer;
,'\ 0'告诉它停止添加的位置。