套接字究竟是什麼
如果你知道linux系統中程序間通訊的方式,就應該知道套接字也是其中一種。但套接字特別之處在於它不僅可以用來實現同一臺主機上程序間的通訊,還可以用來實現主機間的程序間的通訊。通訊的雙方各自開啟乙個套接字,套接字之間通過通訊鏈路相連。
如果把兩個套接字之間的『連線』比喻成『水管』,那麼套接字就是『水龍頭』
unix有一句格言:everything is a file,即『萬物皆檔案』,套接字也不例外。那麼如何把套接字和檔案聯絡起來呢? 答案就是通過下面這張圖。
其中task_struct表示乙個程序,files_struct中的fd_array表示該程序開啟的所有描述符,對於套接字來說,與其他型別檔案的區別就是最終f_op指向的是socket_file_ops。不過,可以看到,這裡的socket_file_ops只有一些通用的操作,並沒有send和recv。特有的操作通過 socketcall() 區分的。
socket 和 sock
終於到今天的主角了。實際上,對每乙個新建立的套接字,核心協議棧都會建立struct socket和struct sock兩個資料結構。這兩個結構就像孿生兄弟,struct socket面向使用者空間,struct sock面向核心空間。
struct socketstruct socket簡化版的結構如下:
struct socket ;
其中type表示協議,這是在建立套接字的時候的protocol引數確定的
int socket(int domain, int type, int protocol);
1file指標指向上面那張圖中的struct file結構,通過它,socket便與檔案系統關聯了起來。
sk指向孿生的兄弟sock結構。
socket結構中最重要的要數ops指標了,根據協議型別,它指向一種特定協議的實現。比如tcp的就是inet_stream_ops,icmp、udp協議對應inet_dgram_ops,rawip對應的是inet_sockraw_ops同樣地,這些也都在建立套接字的時候就決定了。
struct proto_ops的簡化版本的結構如下
struct proto_ops
其中的介面名字是不是很熟悉?是的,它們和進行網路程式設計時呼叫的c庫中函式名字是一樣的。以sendmsg為例,真實的呼叫過程是這樣
即當使用者呼叫sendmsg時,核心會找到描述符fd對應的struct socket結構,然後呼叫sock->ops->sendmsg執行特定協議的傳送。
那麼,ops欄位什麼時候被賦值呢?答案是,在建立struct sock結構前。
struct sock_common ;
struct sock ;
其中最重要的字段就是skc_prot,它也是協議相關的。作為struct socket結構的孿生兄弟,struct sock結構也是在使用者建立套接字時就建立的。
sock_alloc建立了struct socket結構,隨後,根據使用者傳入的family,查詢陣列net_families,找到對應的函式指標,呼叫create.
net_families儲存著核心啟動時註冊(通過sock_register)的 socket protocol handler,比如以下幾種:
static const struct net_proto_family inet_family_ops = ;
static const struct net_proto_family netlink_family_ops = ;
static const struct net_proto_family packet_family_ops = ;
static const struct net_proto_family unix_family_ops = ;
如果我們建立套接字時指定的family是pf_inet,那麼此時我們就會呼叫inet_create
static int inet_create(struct net *net, struct socket *sock, int protocol,
int kern)
else
if (ipproto_ip == answer->protocol)
break;
} err = -eprotonosupport;
} sock->ops = answer->ops;
sk = sk_alloc(net, pf_inet, gfp_kernel, answer_prot, kern);
if (sk->sk_prot->init)
}
首先是從inetsw陣列搜尋匹配對應的協議,inetsw稱為協議開關表,核心啟動時,通過inet_register_protosw進行註冊。比如下面幾項都會被註冊
inetsw中註冊的每種協議都有ops和prot兩個字段,前者與struct socket結構關聯到一起,後者與struct sock關聯到一起。在inet_create中,struct socket的ops欄位和struct sock的sk_prot欄位被賦值。
以我們建立的套接字型別是tcp為例,此時struct socket和struct sock的關係如下:
還是繼續剛才sendmsg的過程,由於struct socket的ops指向inet_stream_ops,所以實際呼叫的就是inet_sendmsg
套接字的秘密 socket與sock
那麼如何把套接字和檔案聯絡起來呢?答案就是通過下面這張圖。其中task struct表示乙個程序,files struct中的fd array表示該程序開啟的所有描述符,對於套接字來說,與其他型別檔案的區別就是最終f op指向的是socket file ops。不過,可以看到,這裡的socket f...
什麼是Socket,與SSL有什麼聯絡?
socket中文意思是套接字,而套接字則是網路通訊的基石,是支援tcp ip協議的路通訊的基本操作單元。我們可以將套接字看作不同主機間的程序進行雙間通訊的端點,它構成了單個主機內及整個網路間的程式設計介面。套接字存在於通訊域中,通訊域是為了處理一般的執行緒通過套接字通訊而引進的一種抽象概念。套接字通...
深入理解阻塞socket和非阻塞socket
什麼是阻塞socket,什麼是非阻塞socket。對於這個問題,我們要先弄清什麼是阻塞 非阻塞。阻塞與非阻塞是對乙個檔案描述符指定的檔案或裝置的兩種工作方式。阻塞的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀或者暫時不可寫,程式就進入等待狀態,直到有東西可讀或者可寫為止。非阻塞的意...