使用socket 函式建立套接字

2021-07-12 06:17:25 字數 2298 閱讀 4805

在linux中,一切都是檔案,除了文字檔案、原始檔、二進位制檔案等,乙個硬體裝置也可以被對映為乙個虛擬的檔案,稱為裝置檔案。例如,stdin 稱為標準輸入檔案,它對應的硬體裝置一般是鍵盤,stdout 稱為標準輸出檔案,它對應的硬體裝置一般是顯示器。對於所有的檔案,都可以使用 read() 函式讀取資料,使用 write() 函式寫入資料。

「一切都是檔案」的思想極大地簡化了程式設計師的理解和操作,使得對硬體裝置的處理就像普通檔案一樣。所有在linux中建立的檔案都有乙個 int 型別的編號,稱為

檔案描述符(file descriptor)

。使用檔案時,只要知道檔案描述符就可以。例如,stdin 的描述符為 0,stdout 的描述符為 1。

在linux中,socket 也被認為是檔案的一種,和普通檔案的操作沒有區別,所以在網路資料傳輸過程中自然可以使用與檔案 i/o 相關的函式。可以認為,兩台計算機之間的通訊,實際上是兩個 socket 檔案的相互讀寫。

檔案描述符有時也被稱為

檔案控制代碼(file handle)

,但「控制代碼」主要是 windows 中術語,所以本教程中如果涉及到 windows 平台將使用「控制代碼」,如果涉及到 linux 平台將使用「描述符」。在 linux 下使用 標頭檔案中 socket() 函式來建立套接字,原型為:

int socket(int af, int type, int protocol);
1) af 為位址族(address family),也就是 ip 位址型別,常用的有 

af_inet

和 af_inet6

。af 是「address family」的簡寫,inet是「inetnet」的簡寫。af_inet 表示 ipv4 位址,例如 127.0.0.1;af_inet6 表示 ipv6 位址,例如 1030::c9b4:ff12:48aa:1a2b。

大家需要記住127.0.0.1,它是乙個特殊ip位址,表示本機位址,後面的教程會經常用到。

你也可以使用pf字首,pf是「protocol family」的簡寫,它和af是一樣的。例如,pf_inet 等價於 af_inet,pf_inet6 等價於 af_inet6。
2) type 為資料傳輸方式,常用的有 

sock_stream

和 sock_dgram

,在《socket是什麼意思

》一節中已經進行了介紹。

3) protocol 表示傳輸協議,常用的有 

ipproto_tcp

和 ipptoto_udp

,分別表示 tcp 傳輸協議和 udp 傳輸協議。

有了位址型別和資料傳輸方式,還不足以決定採用哪種協議嗎?為什麼還需要第三個引數呢?

正如大家所想,一般情況下有了 af 和 type 兩個引數就可以建立套接字了,作業系統會自動推演出協議型別,除非遇到這樣的情況:有兩種不同的協議支援同一種位址型別和資料傳輸型別。如果我們不指明使用哪種協議,作業系統是沒辦法自動推演的。

該教程使用 ipv4 位址,引數 af 的值為 pf_inet。如果使用 sock_stream 傳輸資料,那麼滿足這兩個條件的協議只有 tcp,因此可以這樣來呼叫 socket() 函式:

int tcp_socket = socket(af_inet, sock_stream, ipproto_tcp);  //ipproto_tcp表示tcp協議
這種套接字稱為 tcp 套接字。

如果使用 sock_dgram 傳輸方式,那麼滿足這兩個條件的協議只有 udp,因此可以這樣來呼叫 socket() 函式:

int udp_socket = socket(af_inet, sock_dgram, ipproto_udp);  //ipproto_udp表示udp協議
這種套接字稱為 udp 套接字。

上面兩種情況都只有一種協議滿足條件,可以將 protocol 的值設為 0,系統會自動推演出應該使用什麼協議,如下所示:

int tcp_socket = socket(af_inet, sock_stream, 0);  //建立tcp套接字

int udp_socket = socket(af_inet, sock_dgram, 0); //建立udp套接字

後面的教程中多採用這種簡化寫法。windows 下也使用 socket() 函式來建立套接字,原型為:
socket socket(int af, int type, int protocol);
除了返回值型別不同,其他都是相同的。windows 不把套接字作為普通檔案對待,而是返回 socket 型別的控制代碼。請看下面的例子:
socket sock = socket(af_inet, sock_stream, 0);  //建立tcp套接字

socket 函式用法詳解 建立套接字

不管是 windows 還是 linux,都使用 socket 函式來建立套接字。socket 在兩個平台下的引數是相同的,不同的是返回值。在 socket是什麼 一節中我們講到了 windows 和 linux 在對待 socket 方面的區別。linux 中的一切都是檔案,每個檔案都有乙個整數型...

socket 函式用法詳解 建立套接字

不管是 windows 還是 linux,都使用 socket 函式來建立套接字。socket 在兩個平台下的引數是相同的,不同的是返回值。在 socket是什麼 一節中我們講到了 windows 和 linux 在對待 socket 方面的區別。linux 中的一切都是檔案,每個檔案都有乙個整數型...

socket 函式用法詳解 建立套接字

不管是 windows 還是 linux,都使用 socket 函式來建立套接字。socket 在兩個平台下的引數是相同的,不同的是返回值。在 socket是什麼 一節中我們講到了 windows 和 linux 在對待 socket 方面的區別。linux 中的一切都是檔案,每個檔案都有乙個整數型...