1. 程式人生 > >c++解析tcp頭部遇到的大小端轉換問題

c++解析tcp頭部遇到的大小端轉換問題

首先要明白大端儲存和小端儲存的問題,windows系統使用小端儲存,而網路傳輸中的資料採用的是大端儲存。

關於大小端儲存

網上流傳的tcp頭部的結構體是這樣的

// TCP頭部(20位元組)
typedef struct _tcp_header
{
	unsigned short	sport;				// 源埠號
	unsigned short	dport;				// 目的埠號
	unsigned int	seq_no;				// 序列號
	unsigned int	ack_no;				// 確認號
	unsigned char	thl:4;				// tcp頭部長度
	unsigned char	reserved_1:4;		// 保留6位中的4位首部長度
	unsigned char	reseverd_2:2;		// 保留6位中的2位
	unsigned char	flag:6;				// 6位標誌 
	unsigned short	wnd_size;			// 16位視窗大小
	unsigned short	chk_sum;			// 16位TCP檢驗和
	unsigned short	urgt_p;				// 16為緊急指標
}tcp_header;

一開始,我也是使用這樣的結構體進行資料分析,但是得到的結果總是和wireshark得到的結果相左。

後來我意識到這其中 thl 一直到 flag 這四個結構體成員是一起儲存在一個unsigned short型別的資料中的。

unsigned short是小端儲存的時候,在其中的順序是這樣的,而網路資料是大端儲存方式,因此應該先將這四個變數整個進行一個大小端儲存方式轉換然後再取標誌位的值。

後來我改用了這樣的結構體

typedef struct _tcp_header
{
    unsigned short	sport;				// 源埠號
    unsigned short	dport;				// 目的埠號
    unsigned int	seq_no;				// 序列號
    unsigned int	ack_no;				// 確認號
 
 
    unsigned short  flag;               //16位標誌
 
 
 
 
    unsigned short	wnd_size;			// 16位視窗大小
    
unsigned short chk_sum; // 16位TCP檢驗和
    unsigned short	urgt_p;				// 16為緊急指標
}tcp_header;

就是把4位首部長度、6位保留位和6位標誌位一起作為一個unsigned short型別的flag,在處理的時候先將大端儲存方式轉換成小端儲存方式,然後再按位取值就得到和wireshark相同的結果了。