【发布时间】:2020-02-17 16:15:35
【问题描述】:
我正在尝试使用 C++ 中的 GO 和 TCP 服务器从 TCP 客户端发送 Base64 编码图像。
这里是 C++ Receiver 的代码 sn-p
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 客户端代码 sn-p.
//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。
在将接收到的字符串保存在文件中时,我在字符串中看到 字符。
我正在为 c++ 套接字使用 winsock2.h。
【问题讨论】:
-
recv不一定会返回缓冲区中可以容纳的字节数 - 该函数返回实际返回的字节数作为其结果。你应该考虑到你目前所做的output+=buffer;。 -
char buffer[bufferSize];-- 这不是有效的 C++。使用std::vector<char> buffer(bufferSize); -
见stackoverflow.com/questions/4840535/c-recv-problem 你可能会遇到同样的问题,因为你将信息写入同一个缓冲区。 (当函数返回时,您永远无法确定将 100% 的消息放入缓冲区,因此您必须将其添加到“完整消息缓冲区”中)
-
您可能还有另一个问题:由于消息永远不会完全进入缓冲区,因此您可能会在缓冲区中截断“
”,因此您永远找不到它(C++ 比网络更快所以你可能会每 2-3 个字符返回一个函数;) -
另一个问题:在
recv调用之后,if (iResult == 0) { continue; }是错误的。 只有次您将获得零返回值是如果/当您的对等方已断开连接。通过使用continue,您只需重复recv,这将再次返回0,从而导致无限循环。