端口號回顧
? ? ? ? 端口號的作用類似pid,用來標識進程的唯一性。只是為了與系統解耦,所以有了端口號。
通過ip來確定唯一主機,再通過端口號找到指定的進程。就可以讓全網內唯一的兩個進程通信了。
????????所以一個完整的報文至少要攜帶ip和端口號,ip是在網絡層協議來維護的本章不做講解,而端口號是在傳輸層協議中維護的,傳輸層協議常用的兩種:UDP協議和TCP協議,本章將要講解的是UDP協議,TCP協議在下一期進行講解。
端口號:2字節(16個比特位)其中:
- 0 - 1023: 知名端口號, HTTP, FTP, SSH 等這些廣為使用的應用層協議, 它們的端口號都是固定的。
- 1024 - 65535: 操作系統動態分配的端口號. 客戶端程序的端口號, 就是由操作系統從這個范圍分配的
認識知名端口號
有些服務器是非常常用的, 為了使用方便, 人們約定一些常用的服務器), 都是用以下這些
固定的端口號:
- ssh 服務器, 使用 22 端口
- ftp 服務器, 使用 21 端口
- telnet 服務器, 使用 23 端口
- http 服務器, 使用 80 端口
- https 服務器, 使用 443 端口
執行下面的命令, 可以看到知名端口號:
?cat /etc/services
思考:
- 一個進程是否可以 bind 多個端口號?
- 一個端口號是否可以被多個進程 bind?
? ? ? ? 答1:一個進程是可以綁定多個端口號的,當一個進程提供多個不同服務時,就可以通過綁定多個端口來優化。只要一個端口能確定唯一進程就行。
? ? ? ? 答2:不能。要保證一個端口確定唯一進程。
UDP協議端格式
- 16位源端口和16位目的端口用來確定兩個唯一進程,這沒啥說的。
- 16位UDP長度:數據字段的大小不是固定的,所以該字段來表示整個數據報(UDP 首部+UDP 數據)的長度。
- 16位UDP檢驗和:不保證可靠性,校驗和是唯一確定數據是否有效的機制。因為在數據傳輸過程中物理干擾、路由錯誤等可能導致數據損壞。
UDP協議特點
- 無連接: 知道對端的 IP 和端口號就直接進行傳輸, 不需要建立連接。
- 不可靠:報文發出去任務就完成了,報文是否丟失不關心。注意這不是缺點,是特點!
- 面向數據報:發10次,收10次。而TCP協議是面向字節流的,類似自來水。
- 緩沖區:UDP沒有發送緩沖區,直接發(TCP有發送緩沖區是為了方便重傳)。有接收緩沖區,出于效率考量,忙的時候,可以緩一緩。緩沖區滿了就把報文丟棄。為全雙工。
內核源碼
UDP協議格式其實就是一個結構體,源碼如下:
struct udphdr {unsigned short src_port;unsigned short dst_port;unsigned short len;unsigned short chksum;
};
????????在把數據交付給傳輸層時,數據在應用層必做序列化和反序列化。當然可直接用結構體變量代替,但非常不推薦(結構體存在內存對齊有內存浪費,與其他語言不兼容,需要考慮字節序問題等等)。
? ? ? ? 注:即使通信雙方操作系統完全不同,但網絡內核部分一定相同(所以能夠通信)。操作系統內核都是使用c語言實現。
????????在OS內部一定會同時存在大量的報文,而這些報文可分布在各個協議層,OS必須管理這些報文。如果管理?先描述,再組織。如何描述:內核源碼中結構體 struct sk_buff,如下:
struct sk_buff
{struct sk_buff * next; /* Next buffer in list */struct sk_buff * prev; /* Previous buffer in list */struct sk_buff_head * list; /* List we are on */
#if CONFIG_SKB_CHECKint magic_debug_cookie;
#endifstruct sk_buff *link3; /* Link for IP protocol level buffer chains */struct sock *sk; /* Socket we are owned by */unsigned long when; /* used to compute rtt's */struct timeval stamp; /* Time we arrived */struct device *dev; /* Device we arrived on/are leaving by */union {struct tcphdr *th;struct ethhdr *eth;struct iphdr *iph;struct udphdr *uh;unsigned char *raw;/* for passing file handles in a unix domain socket */void *filp;} h;union { /* As yet incomplete physical layer views */unsigned char *raw;struct ethhdr *ethernet;} mac;struct iphdr *ip_hdr; /* For IPPROTO_RAW */unsigned long len; /* Length of actual data */unsigned long csum; /* Checksum */__u32 saddr; /* IP source address */__u32 daddr; /* IP target address */__u32 raddr; /* IP next hop address */__u32 seq; /* TCP sequence number */__u32 end_seq; /* seq [+ fin] [+ syn] + datalen */__u32 ack_seq; /* TCP ack sequence number */unsigned char proto_priv[16]; /* Protocol private data */volatile char acked, /* Are we acked ? */used, /* Are we in use ? */free, /* How to free this buffer */arp; /* Has IP/ARP resolution finished */unsigned char tries, /* Times tried */lock, /* Are we locked ? */localroute, /* Local routing asserted for this frame */pkt_type, /* Packet class */pkt_bridged, /* Tracker for bridging */ip_summed; /* Driver fed us an IP checksum */
#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1 /* To all */
#define PACKET_MULTICAST 2 /* To group */
#define PACKET_OTHERHOST 3 /* To someone else */unsigned short users; /* User count - see datagram.c,tcp.c */unsigned short protocol; /* Packet protocol from driver. */unsigned short truesize; /* Buffer size */atomic_t count; /* reference count */struct sk_buff *data_skb; /* Link to the actual data skb */unsigned char *head; /* Head of buffer */unsigned char *data; /* Data head pointer */unsigned char *tail; /* Tail pointer */unsigned char *end; /* End pointer */void (*destructor)(struct sk_buff *); /* Destruct function */__u16 redirport; /* Redirect port */
};
封包和解包的本質理解
在以上源碼中我們主要關注兩個部分:
該字段說明報文用了鏈表結構來維護,對報文進行操作的本質就是鏈表的增刪改查。
怎么體現不同協議層報文呢?如下字段:
變量 | 指向位置 | 功能 |
---|---|---|
head | 緩沖區的起始地址 | 指向整個數據包內存的頭部(包括預留的“頭空間”)。 |
data | 當前協議層頭部 | 隨著協議棧處理,動態移動: 接收時:從MAC頭 → IP頭 → TCP(或UDP)頭 → 應用數據。 發送時:反向移動。 |
tail | 當前有效數據的末尾 | 標識實際數據的結束位置(如應用層數據的末尾)。 |
end | 緩沖區的結束地址 | 指向整個數據包內存的尾部(包括預留的“尾空間”)。 |
[head,end]:緩沖區大小。
[data,tail]:報文。封裝和解包本質:移動data指針在緩沖區的位置,加減對應層協議長度。
非常感謝您能耐心讀完這篇文章。倘若您從中有所收獲,還望多多支持呀!