時間版本修改
2023年4月2日
初稿乙個典型的協議頭設計如下:
字段意義
包頭標識_uint8[2]
協議版本號_uint8
當前版本號
clienttype_uint8
客戶端型別(pc,安卓等)
clientversion_uint16
client版本
versiontype_uint8
client版本型別(區分簡繁體等)
userid_uint32
登入使用者id(使用者id)
包型別標誌_uint8
(應答or推送)
serialno_uint32
命令序列號,每傳送乙個命令後加1
cmd_uint16
協議號(區分上層業務)
bodylength_uint32
協議包體長度(本文重點)
reserved
任意byte保留位元組(保留當然不能太長羅)
void cmywintcpsocket::onreceive(int nerrorcode)
//記錄本次套接字被啟用的時間
m_usocketactivetime = ::gettickcount();
dword nbytes = 0;
if (!ioctl(fionread, &nbytes) || nbytes == 0) //fionread返回套接字上排隊的第乙個資料報大小
//此時套接字中可獲取的資料有nbytes個位元組
//開始讀取資料
char *preceivebuffer = new char[nbytes]; //有多少讀多少,一次性讀完
int nread = casyncsocketex::receive(preceivebuffer, nbytes); //nread是實際讀取到的資料
if (nread <= 0) //出現異常,需要退出
int ncurrentoffset = 0; //記錄讀取本次的套接字資料的offset(偏移量)
int nleftsize = nread; //本次套接字返回的資料,剩下的未讀取的位元組數
char *poffsetbuffer = preceivebuffer;
std::vectorvecrecvpacks; //tagrecvpack表示乙個收到的應用層的包,從成員變數offset來判斷當前獲取的位元組數
do //判斷上次呼叫onreceive的資料是否已經讀取完頭部,
if (m_recvpack.uheadoffset < nheaderlen)
m_recvpack.ubodytotal = nbodylength;
if (m_recvpack.ubodytotal == 0) //乙個空包,以前的邏輯是直接拋棄的,現在空包也要
//包體過大,應該是資料錯亂了,剩下的包已經不知道怎麼解析了,只能斷開
else if (m_recvpack.ubodytotal > tcp_protocol_packet_max_length)
//-----------2. 頭部讀完,開始做準備或者容錯之類的工作-----------//
//-----------3. 建立好乾淨的包體,用以儲存包體資料-----------//
if (m_recvpack.ubodytotal > 0)
//-----------3. 建立好乾淨的包體,用以儲存包體資料-----------//}}
//開始讀取包體
else if (m_recvpack.pheadbuffer && m_recvpack.uheadoffset == nheaderlen)
if (m_recvpack.ubodyoffset == m_recvpack.ubodytotal && m_recvpack.pbodybuffer != null) //資料讀取完成
//---4.根據協議頭帶上的包體長度,直接解析包體,如果套接字buffer不夠長,要先存起來,等待下次onreceive呼叫時再粘包---//
}else
} while (nleftsize > 0);
//還回資料
mf_delete1d(preceivebuffer);
//本次解析出來的包,每乙個依次往上層丟擲**
auto uconnectordersession = m_uconnectordersession;
for (auto it : vecrecvpacks)
if (uconnectordersession != m_uconnectordersession)
if (it.ubodytotal == 0)
else
}}
TCP的粘包問題以及資料的無邊界性
上節我們講到了socket緩衝區和資料的傳遞過程,可以看到資料的接收和傳送是無關的,read recv 函式不管資料傳送了多少次,都會盡可能多的接收資料。也就是說,read recv 和 write send 的執行次數可能不同。例如,write send 重複執行三次,每次都傳送字串 abc 那麼...
TCP協議 HTTPS協議的理解
tcp tcp是一種可靠的傳輸協議,為什麼說它可靠呢,因為它有 三次握手 為什麼握三次手就可靠了,握兩次或者一次會怎樣?hi,我可以跟你拉小手手嗎?ok啊,那你現在方便跟我牽嗎?伸出手 好的,我已經抓住你的手了 https是加了安全驗證的http協議。可以這麼說,當你跟某個遠端的小夥伴通過網路傳輸資...
TCP協議是如何確保可靠傳輸的?
關於 tcp協議如何確保可靠傳輸 這個問題,網上的資料參差不齊。近期開始在圖書館讀一些教材,帶著問題讀了以下書目的關於tcp的章節,總結記錄了下來。因而以上3點,可靠傳輸的重擔交予到了tcp之上。為了實現可靠傳輸的目的,tcp使用4個解決方案 面向連線的傳輸機制 超時重傳控制 可變滑動視窗流量控制 ...