[英]Sending Large Base64 String over TCP Socket
I am trying to send a Base64 encoded image from TCP client using GO and TCP server in 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(), '\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)
}
嘗試過的方法:
觀察:
客戶端發送的字符串長度是固定的,而收到 function 后的字符串長度較大且隨機。 示例:Go 客戶端字符串長度為 25243。對於相同的字符串,當我在循環中運行發送和接收時,接收后的長度為 25243、26743、53092、41389、42849。
在將接收到的字符串保存在文件中時,我在字符串中看到 <0x7f> <0x02> 字符。
我將 winsock2.h 用於 c++ 插座。
您將接收到的數據視為 C 字符串 - 以 0 字節結尾的字節序列 - 這是不正確的。
recv
接收一些字節並將它們放入buffer
中。 假設它收到了 200 個字節。
然后你做strstr(buffer,eom_flag);
. strstr
不知道收到了 200 個字節。 strstr
從緩沖區的開頭開始,一直查找,直到找到一個或一個 0 字節。 即使您沒有收到一個,它也有可能在緩沖區的其他 824 個字節中找到一個。
然后你做output += buffer;
. 這也將緩沖區視為以 0 字節結尾。 這將查看整個緩沖區(不僅僅是前 200 個字節)以找到一個 0 字節。 然后它將到該點的所有內容添加到output
中。 同樣,它可能會在緩沖區的最后 824 個字節中找到一個 0 字節,並添加太多數據。 它可能在緩沖區中根本找不到 0 字節,然后它將繼續從存儲在 memory 中buffer
旁邊的其他變量中添加額外數據。 或者它可能會在前 200 個字節中找到一個 0 字節,然后停在那里(但前提是您發送了一個 0 字節)。
您應該注意接收到的字節數(即iResult
)並將那么多字節添加到 output。 你可以使用:
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' 告訴它在哪里停止添加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.