深度探索Linux核心之傳送乙個UDP資料報

2021-06-02 19:49:53 字數 1884 閱讀 8544

注:下面會好好幾篇文章,我都摘自同乙個作者,他是一位前輩,和高人。我在此先表示感謝,在文章的後面我會注出作者和位址。我這樣做,主要是防止自己以後找不到這些經典的好文章。出自

在socket程式設計中,傳送資料報文可供使用的api函式有send,sendto和sendmsg,下面是關於前兩個系統呼叫的原型:

#include

ssize_t send( int socket, const void *buffer, size_t length, int flags );

請注意它的返回值的型別ssize_t,其含義是signed size。從核心**中,我們可以看到,在32位系統上,它是int,在64位系統上,它是long。它常用於表示在某一次操作後,緩衝區中可以被讀或寫的位元組數量。相對應的,還有乙個資料型別size_t,其含義是unsigned size。常用於表示物件本身的大小,操作sizeof的返回值就是該型別,malloc,memcpy等函式的引數中用該型別表示物件的大小,在32位系統上,它是unsigned int,在64位系統上,它是unsigned long。

send執行成功,會返回被傳送出去的資料報文的位元組數,如果執行失敗,則會返回-1(所以不能返回size_t型別),並且可以從errno上查詢到錯誤原因。

#include

ssize_t sendto(int socket, const void *message, size_t length,

int flags, const struct sockaddr *dest_addr,

socklen_t dest_len);

在核心的實現中,send和sendto系統呼叫最終都會呼叫到核心函式:

asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,

struct sockaddr __user *addr, int addr_len)

在send系統呼叫中,引數addr被置為null,addr_len為0。sys_sendto首先根據傳入的描述符fd,找到對應的struct socket結構體。然後構建核心的訊息結構struct msghdr:

struct msghdr ;

msg_name和msg_namelen就是資料報文要發向的對端的位址資訊(即sendto系統呼叫中的addr和addr_len)。當使用send時,它們的值為null和0。msg_iov的定義如下:

struct iovec

;表示存放待傳送資料的乙個緩衝區,iov_base是緩衝區的起始位址,指向message, iov_len是緩衝區的長度,指向length。msg_iovlen是緩衝區的數量,對於sendto和send來講,msg_iovlen都是1。msg_flags即為傳入的引數flags,現在暫時不過多的關注flags的應用。msg_control和msg_controllen暫時不關注。

sys_sendto構建完這些後,呼叫sock_sendmsg繼續執行傳送流程,傳入引數為struct msghdr和資料的長度。忽略中間的一些不重要的細節,sock_sendmsg繼續呼叫__sock_sendmsg,__sock_sendmsg最後呼叫struct socket->ops->sendmsg,即對應套接字型別的sendmsg函式,所有的套接字型別的sendmsg函式都是inet_sendmsg,該函式首先檢查本地埠是否已繫結,無繫結則執行自動繫結,而後呼叫具體協議的sendmsg函式。

下面再來看sendmsg系統呼叫:

#include

ssize_t sendmsg(int socket, const struct msghdr *message, int flags);

可以看到,它跟send和sendto的最大區別就是struc msghdr由使用者來構建完成,對應的核心處理函式是sys_sendmsg。

深度探索Linux核心之自動分配UDP本地埠

在sock dgram型別的套接字的操作函式集的sendmsg成員函式中,每次呼叫對應的第4層協議的sendmsg成員函式時,都會進行埠號的檢查,如果沒有繫結就呼叫協議的成員函式get port進行自動繫結。代表inet域網路層套接字的結構體struct inet sock有兩個埠號相關的成員 u1...

深度探索Linux核心之對組播的支援

對組播資料報的支援由如下幾項組成 若干裝置標誌,乙個裝置函式和乙個資料結構。下面分別對其進行介紹。net device結構體的成員flags是乙個unsigned short型的資料型別,儲存網路介面的一組裝置標誌。對於乙太網網路裝置,核心提供的預設的初始化函式中,這樣給flags賦值 dev fl...

linux核心協議棧 TCP資料傳送之傳送視窗

目錄 1 傳送視窗概述 2 snd una 和 snd wnd 的更新 2.1 傳送視窗初始化 2.1.1 客戶端初始化 2.1.2 伺服器端初始化 2.2 本地接收視窗 rcv wnd 通告 2.2.1 客戶端傳送 2.2.2 伺服器傳送 2.3 傳輸過程中更新傳送視窗 2.3.1 傳送視窗更新條...