socket與檔案描述符
阿新 • • 發佈:2019-02-18
在Linux程式設計時,無論是在操作檔案還是網路操作時都能夠通過檔案描述符來read或者write。之前在沒有接觸C++的時候,不懂面向物件的那套東西。自從學習了C++以及面向物件的一些知識以後突然對Linux這套檔案描述符有了稍微深刻的認識。
怎麼說呢,Linux這一套檔案機制就相當於面向物件裡面的多型,拿到一個檔案描述符都可以進行read或者write。但是具體的read和write卻跟對應檔案描述符的具體實現不同。比如socket的就是走網路,普通檔案的就是走磁碟IO。
下面一張UML類圖大概表現出了Linux檔案描述符的大概意思:
當然,為了將不同的型別的I/O與對應的檔案描述符繫結,則是需要不同的初始化函式的。在C++中有建構函式跟編譯器幫助搞定,在C函式裡只能自己動手豐衣足食了。
普通檔案就通過open函式,指定對應的檔案路徑,作業系統通過路徑能夠找到對應的檔案系統型別,如ext4啊,fat啊等等。
如果是網路呢,就通過socket函式來初始化,socket函式就通過(domain, type, protocol)來找到對應的網路協議棧,比如TCP/IP,UNIX等等。
整個Linux 檔案系統的結構差不多就這個意思,socket跟他繫結也是為了統一介面。
所以網路相關的呼叫,如connect, bind等等,第一步基本上就是通過檔案描述符找到對應的核心socket結構,然後在進行對應的操作。
-
SYSCALL_DEFINE2(
-
{
-
struct socket *sock;
-
int err, fput_needed;
-
int somaxconn;
- /* 通過檔案描述符獲得 kernel socket結構, 並且增加此結構的引用計數 */
-
sock = sockfd_lookup_light(fd, &err, &fput_needed);
-
if (sock) {
- /* 進行檢測,看看是否滿足系統設計的需求,功能上不重要 */
-
somaxconn = sock_net(sock-
-
if ((unsigned)backlog > somaxconn)
-
backlog = somaxconn;
- /* 檢測此呼叫是否安全 */
-
err = security_socket_listen(sock, backlog);
- /* 執行具體的listen操作,TCP啊,或者是其他網路協議等等,這個ops是在socket時候繫結的 */
-
if (!err)
-
err = sock->ops-
- /* 減少kernel socket的引用計數 */
-
fput_light(sock->file, fput_needed);
-
}
-
return err;
- }