亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過 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 關注
  • 197 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號