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

我正在尝试使用 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)

        }

尝试过的方法:

  • 增加 C++ 接收器中的缓冲区大小。

  • 从 C++ 接收器中的字符串末尾删除空字符。

观察结果:

  • 客户端发送的字符串长度是固定的,而接收函数后的字符串长度较大且随机。示例:Go 客户端字符串长度为 25243。对于同一个字符串,当我在循环中运行发送和接收时接收后的长度为 25243、26743、53092、41389、42849。

  • 将接收到的字符串保存在文件中时,我在字符串中看到 <0x7f> <0x02> 字符。

我正在使用winsock2.h 作为c++ 套接字。


蝴蝶刀刀
浏览 143回答 1
1回答

撒科打诨

您将接收到的数据视为 C 字符串(以 0 字节结尾的字节序列),这是不正确的。recv接收一些字节并将它们放入buffer.&nbsp;假设它收到了 200 字节。那么你就这样做strstr(buffer,eom_flag);。strstr不知道已收到 200 字节。strstr从缓冲区的开头开始,一直查找,直到找到 、 或 0 字节。即使您没有收到,它也有可能在缓冲区的其他 824 字节中找到 a。那你就做吧output += buffer;。这也将缓冲区视为以 0 字节结尾。这将查看整个缓冲区(不仅仅是前 200 个字节)以查找 0 字节。然后它将把截至该点的所有内容添加到output.&nbsp;同样,它可能会在缓冲区的最后 824 字节中找到 0 字节,并添加过多的数据。它可能根本在缓冲区中找不到 0 字节,然后它将继续从存储在buffer内存中的其他变量中添加额外的数据。或者它可能会在前 200 个字节中找到 0 字节,并在那里停止(但前提是您发送了 0 字节)。您应该做的是注意接收到的字节数(即iResult)并将这些字节添加到输出中。你可以使用:output.insert(output.end(),&nbsp;buffer,&nbsp;buffer+iResult);另外(正如 Phillipe Thomassigny 在评论中指出的那样),“”可能不会立即全部收到。您可能会单独收到“”。您应该检查是否output有“”,而不是检查是否buffer有“”。(这对性能的影响留给读者作为练习)顺便说一下,这一行目前没有做任何事情:output.erase(std::find(output.begin(),&nbsp;output.end(),&nbsp;'\0'),&nbsp;output.end());因为 '\0' 永远不会被添加到output,因为对于output += buffer;,'\0' 告诉它在哪里停止添加。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go