流式套接字程式設計中收包問題

2021-05-28 02:17:50 字數 1459 閱讀 4401

tcp傳輸是提供給使用者一種可靠的面向連線的資料服務,開銷當然也大。在程式設計實踐中對應於流式套接字網路程式設計了。

對於傳送資料且不作論,咱們很容易遇到乙個問題就是套接字在讀取接收緩衝的時候,我們以什麼辦法來保證讀取一次完整的應用資料報?

面向連線的套接字操作中,尤其說在接收訊息過程中,我們是輸入一資料儲存來呼叫套接字接收訊息,當有可讀的內容時,會返回寫入輸入資料區實際位元組數。這很容易造成的問題就是,讀到的資料很有可能不是乙個完整的包,或可以是多個資料報粘連一起了等等現象。從網上隨便一搜tcp粘包現象,就一堆話題出來。當然粘包現象只是我們要考慮的一種,對與對策就是分包演算法。但這裡,不獨細究粘包現象與分包演算法。

因為除了粘包問題,同時我們接收也可能出現資料報被分片而截斷等種種問題。最終我們想要的是怎麼保證收取訊息過程中從讀出的資料內容中將獨個完整的資料報分離出來,並交付於邏輯層處理。

okay,多餘的不多說。下面針對單個套接字的收取執行緒迴圈來設計相應對策。**見下

執行緒迴圈,套接字訊息收取部分**

// the socke recv thread code

msglen = recv(s, buffer, buffsz, 0);

if (msglen>0)

}

packet_lengthof   為從某個資料頭得到該包的長度

get_complete_packet 重點函式,完整包檢出** 

// function definition, the complete packet retrive from the buffer

char* get_complete_packet(char* buffer, int length)

; static int __thread offset = 0; // tls

int pkt_len = packet_lengthof(offset == 0 ? buffer : packet)

int szcpy = (length > pkt_len ? pkt_len : length);

memcpy(packet + offset, buffer, szcpy);

offset += szcpy;

char *packet_ret = null;

if (offset == pkt_len)

return packet_ret;

}

以上**並不是直接可執行 get_complete_packet 中用到了區域性靜態變數,為了使得該函式能夠多執行緒可重入,將其標識為執行緒本地儲存物件了,在gcc下加__thread表示。

另外對於取個完整資料報長度 packet_lengthof 沒有給出定義,因為這必須依據實際應用協議來定。能夠表示明白是應用層的資料報長度就不錯了。

由於本人近來專案都要求使用c開發,所以寫的全是些過程演算法。本來我還是甚是喜歡c++的,他的種種高階特性為眾多程式設計師所持捧,我也不例外。

TCP流式套接字的基本程式設計

面向連線的客戶 伺服器程式工作模型 伺服器端程式 include pragma comment lib,ws2 32 include int main else 建立用於監聽的流式套介面s socket s socket af inet,sock stream,ipproto tcp if s in...

TCP流式套接字的select模式程式設計

選擇 select 模型是winsock中最常見的 i o模型。核心便是利用 select 函式,實現對 i o的管理!利用 select 函式來判斷某socket上是否有資料可讀,或者能否向乙個套接字寫入資料,防止程式在socket處於阻塞模式中時,在一次 i o 呼叫 如send或recv ac...

linux網路程式設計(unix域流式套接字)

unix域套接字 流式 1.標頭檔案 include 2.資料結構 struct sockaddr un 3.服務端流程 1.建立套接字 sockfd socket af unix,sock stream,0 2.繫結位址到socket struct sockaddr un server addr ...