为了账号安全,请及时绑定邮箱和手机立即绑定

通过 TCP 套接字发送大型 Base64 字符串

通过 TCP 套接字发送大型 Base64 字符串

Go
蝴蝶刀刀 2023-07-31 15:35:18
我正在尝试使用 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 connectionconnection, _ := net.Dial("tcp", "localhost"+":"+PortNumber)if _, err := fmt.Fprintf(connection, B64img+"<EOF>"); err != nil {            log.Println(err)            panic(err)        }尝试过的方法:增加 C++ 接收器中的缓冲区大小。从 C++ 接收器中的字符串末尾删除空字符。观察结果:客户端发送的字符串长度是固定的,而接收函数后的字符串长度较大且随机。示例:Go 客户端字符串长度为 25243。对于同一个字符串,当我在循环中运行发送和接收时接收后的长度为 25243、26743、53092、41389、42849。将接收到的字符串保存在文件中时,我在字符串中看到 <0x7f> <0x02> 字符。我正在使用winsock2.h 作为c++ 套接字。
查看完整描述

1 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

您将接收到的数据视为 C 字符串(以 0 字节结尾的字节序列),这是不正确的。

recv接收一些字节并将它们放入buffer. 假设它收到了 200 字节。

那么你就这样做strstr(buffer,eom_flag);strstr不知道已收到 200 字节。strstr从缓冲区的开头开始,一直查找,直到找到 、 或 0 字节。即使您没有收到,它也有可能在缓冲区的其他 824 字节中找到 a。

那你就做吧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' 告诉它在哪里停止添加。


查看完整回答
反对 回复 2023-07-31
  • 1 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信