通过 TCP 套接字发送大型 base64 字符串
Sending Large Base64 String over TCP Socket
我正在尝试使用 GO 和 TCP 服务器从 TCP 客户端发送 Base64 编码的图像 C++.
这是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(), ' '), 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。对于相同的字符串,接收后的长度当 i 循环中的运行发送和接收是 25243、26743、53092、41389、42849。
在将收到的字符串保存在文件中时,我在字符串中看到<0x7f> <0x02>字符。
我正在使用winsock2.h作为c ++套接字。
您将接收到的数据视为 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(), ' '), output.end());
因为 '\0' 永远不会被添加到output
中,因为有了output += buffer;
,一个 '\0' 告诉它在哪里停止添加。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++中高效的大型稀疏块压缩线性方程
- 无法解码base64+deflate数据
- 如何实现高效的算法来计算大型数据集的多个不同值?
- LMDB:在有限的内存系统中打开大型数据库
- 如何在大型c++项目的可视化代码中设置调试
- 仅在大型阵列上出现合并排序分段错误
- 在堆栈上C++大型多维数组
- atoi() 在应用于大型命令行参数时会产生不正确的值
- 如何在 c++ 中通过 http 发送大型视频文件?
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- 如何将 OpenMP 和 MPI 导入到大型 CLion CMake 项目中?
- Base64 图像编码不正确
- > 64k C++的 DirectX 大型机型
- 使用 RapidXML 解析大型 XML(大小大于 65 KB)文件时出现问题
- 编译时 Base64 解码 C++
- Base64 图像比较
- 堆分配对于大型块中的分页是否更有效?
- 适用于大型数组的无复制线程安全环形缓冲区
- 通过 TCP 套接字发送大型 base64 字符串