過去幾天我正在使用套接字(在C中,沒有套接字編程的經驗)。 其實我必須收集樹莓派上的WiFi數據包,做一些處理,並且必須通過套接字(這兩個設備都連接到網絡中)將格式化的信息發送到另一個設備。以C的速度在C中的套接字上接收不同長度的數據包的連續流?
我面臨的挑戰是通過套接字接收數據。
在發送數據時,數據通過發送端的套接字成功發送,但在接收端,有時會收到一些垃圾或以前的數據。
在發送端(客戶端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//connecting to the server with connect function
send(server_socket, &datalength, sizeof(datalength),0); //datalength is an integer containing the number of bytes that are going to be sent next
send(server_socket, actual_data, sizeof(actual_data),0); //actual data is a char array containing the actual character string data
接收側(服務器端):
int server_socket = socket(AF_INET, SOCK_STREAM, 0);
//bind the socket to the ip and port with bind function
//listen to the socket for any clients
//int client_socket = accept(server_socket, NULL, NULL);
int bytes;
recv(client_socket, &bytes, sizeof(bytes),0);
char* actual_message = malloc(bytes);
int rec_bytes = recv(client_socket, actual_message, bytes,0);
*上面的代碼行是不實際代碼行,但流量和程序是類似的(具有異常處理和評論)。
有時,我可以快速獲取所有數據包的實際數據(沒有任何錯誤和數據包丟失)。但有時候,字節(整數發送來說明下一個事務的字節流的大小)是作爲一個垃圾值接收的,所以我的代碼在那個時候被破壞了。 有時,我在接收端收到的字節數少於預期的字節數(從已收到的整數bytes
中得知)。所以在這種情況下,我檢查這種情況並檢索剩餘的字節。
實際上數據包到達的速率非常高(大約在1000個數據包在不到一秒鐘,我不得不解剖,格式化並通過套接字發送它)。我嘗試了不同的想法(使用SOCK_DGRAMS,但這裏有一些數據包丟失,在事務之間插入一些延遲,爲每個數據包打開並關閉一個新套接字,在接收數據包後添加一個確認),但沒有一個符合我的要求(快速傳輸丟包數爲0的數據包)。
請注意,建議一種通過套接字快速發送和接收不同長度的數據包的方法。
什麼是'actual_data'?它是*所有*充滿數據?有沒有部分填充的緩衝區?因爲,你知道,TCP是一個*流*協議,沒有固定大小的數據包或消息邊界。這意味着你可能並不總是通過單一的「recv」調用發送所有這些內容,你必須循環以確保你能收到所有的數據。 –
此外,由於您正在發送數據長度的「int」值(我假設),您確定沒有任何[* endianness *](https://en.wikipedia.org/wiki/Endianness)問題是什麼?由於在典型的ARM平臺(如R-PI)和典型的x86 PC平臺(如大多數現代臺式計算機)上的排序通常不相同。 –
@Someprogrammerdude'實際數據'就像一個英文文本(WiFi數據包解析和格式化) 是的......我知道它可能不會收到一次電話,因爲我添加了一張支票,如果沒有收到一個電話,我已經添加了代碼來獲取剩餘的數據字節。 實際的問題是與字節的數量,它有時收到一些垃圾值 –