網路IPC 套接字之套接字描述符

2022-05-04 20:03:22 字數 3044 閱讀 8052

套接字是通訊端點的抽象。與應用程式要使用檔案描述符訪問檔案一樣,訪問套接字也需要套接字描述符。套接字描述符在unix系統是用檔案描述符實現的。事實上,許多處理檔案描述符的函式(如read和write)都可以處理套接字描述符。

要建立乙個套接字,可以呼叫socket函式。

#include int socket(int domain, int type, int

protocol);

返回值:若成功則返回檔案(套接字)描述符,若出錯則返回-1

引數domain(域)確定通訊的特性,包括位址格式。表16-1總結了由posix.1指定的各個域。各個域有自己的格式表示位址,而表示各個域的常數都以af_開頭,意指位址族(address family)。

表16-1 套接字通訊域

多數系統還會定義af_local域,這是af_unix的別名。af_unspec域可以代表任何域。歷史上,有些平台支援其他網路協議(如af_ipx為netware協議族),但這些協議的域常數沒有在posix.1標準中定義。

引數type確定套接字的型別,進一步確定通訊特徵。表16-2總結了由posix.1定義的套接字型別,但在實現中可以自由增加對其他型別的支援。

表16-2 套接字型別

引數protocol通常是0,表示按給定的域和套接字型別選擇預設協議。當對同一域和套接字型別支援多個協議時,可以使用protocol引數選擇乙個特定協議。在af_inet通訊域中套接字型別sock_stream的預設協議是tcp(傳輸控制協議)。在af_inet通訊域中套接字型別sock_dgram的預設協議是udp(使用者資料報協議)。下表(摘自apue第3版)列出了為網際網路域套接字定義的協議:

對於資料報(sock_dgram)介面,與對方通訊時是不需要邏輯連線的。只需要送出乙個報文,其位址是乙個對方程序所使用的套接字。

因此資料報提供了乙個無連線的服務。另一方面,位元組流(sock_stream)要求在交換資料之前,在本地套接字和與之通訊的遠端套接字之間建立乙個邏輯連線。

資料報是一種自包含報文。傳送資料報近似於給某人郵寄信件。可以郵寄很多信,但不能保證投遞的次序,並且可能有些信件丟失在路上。每封信件包含接收者的位址,使這封信件獨立於所有其他信件。每封信件可能送達不同的接收者。

相比之下,使用面向連線的協議通常就像與對方打**。首先,需要通過**建立乙個連線,連線建立好之後,彼此能雙向地通訊。每個連線是端到端的通訊通道。會話中不包含位址資訊,就像呼叫的兩端存在乙個點對點的虛擬連線,並且連線本身暗含特定的源和目的地。

對於sock_stream套接字,應用程式意識不到報文界限,因為套接字提供的是位元組流服務。這意味著當從套接字讀出資料時,它也許不會返回所有由傳送者程序所寫的位元組數。最終可以獲得傳送過來的所有資料,但也許要通過若干次函式呼叫得到。

sock_seqpacket套接字和sock_stream套接字很類似,但從該套接字得到的是基於報文的服務而不是位元組流服務。這意味著從sock_seqpacket套接字接收的資料量與對方傳送的一致。流控制傳輸協議(stream control transimission portocol, sctp)提供了網際網路域上的順序資料報服務。

sock_raw套接字提供乙個資料報介面用於直接訪問下面的網路層(在網際網路域中為ip)。使用這個介面時,應用程式負責構造自己的協議首部,這是因為傳輸協議(tcp和udp等)被繞過了。當建立乙個原始套接字時需要有超級使用者特權,用以防止惡意程式繞過內建安全機制來建立報文。

呼叫socket與呼叫open相類似。在兩種情況下,均可獲得用於輸入/輸出的檔案描述符。當不再需要該檔案描述符時,呼叫close來關閉對檔案或套接字的訪問,並且釋放該描述符以便重新使用。

雖然套接字描述符本質上是乙個檔案描述符,但不是所有引數為檔案描述符的函式都可以接受套接字描述符。表16-3總結了到目前為止所討論的大多數使用檔案描述符的函式處理套接字描述符時的行為。未規定的和由實現定義的行為通常意味著函式不能處理套接字描述符。例如,lseek不處理套接字,因為套接字不支援檔案偏移量的概念。

表16-3 使用檔案描述符的函式處理套接字時的行為

套接字通訊是雙向的。可以採用函式shutdown來禁止套接字上的輸入/輸出。

#include int shutdown(int sockfd, int

how);

返回值:若成功則返回0,出錯則返回-1

如果how是shut_rd(關閉讀端),那麼無法從套接字讀取資料;如果how是shut_wr(關閉寫端),那麼無法使用套接字傳送資料;使用shut_rdwr則將同時無法讀取和傳送資料。

能夠使用close關閉套接字,為何還要使用shutdown呢?理由如下:首先,close只有在最後乙個活動引用被關閉時才釋放網路端點。這意味著如果複製乙個套接字(例如採用dup),套接字直到關閉了最後乙個引用它的檔案描述符之後才會被釋放。而shutdown允許使乙個套接字處於不活動狀態,無論引用它的檔案描述符數目多少。其次,有時只關閉套接字雙向傳輸中的乙個方向會很方便。例如,如果想讓所通訊的程序能夠確定資料傳送何時結束,可以關閉該套接字的寫端,然而通過該套接字讀端仍可以繼續接收資料。

本篇博文內容摘自《unix環境高階程式設計》(第2版),僅作個人學習記錄所用。關於本書可參考:

APUE 網路IPC 套接字之套接字選項

套接字機制提供兩個套接字選項介面來控制套接字的行為。乙個介面用來設定選項,另乙個介面允許查詢乙個選項的狀態。可以獲取或設定的三種選項 1 通用選項,工作在所有套接字型別上。2 在套接字層次管理的選項,但是依賴於下層協議的支援。3 特定與某協議的選項,為每個協議所獨有。single unix spec...

網路IPC 套接字

1.套接字是通訊端點的抽象。與應用程式要用檔案描述符訪問檔案一樣,訪問套接字也需要用套接字描述符。套接字描述符在unix系統是用檔案描述符實現的。要建立乙個套接字,可以呼叫socket函式。include int socket int domain,int type,int protocol 返回值...

網路IPC 套接字

套接字描述符 includeint socket int domain,int type,int prootocol 返回值 若成功,返回檔案 套接字 描述符,若出錯,返回 1域 描述af inet ipv4 網際網路域 af inet6 ipv6網際網路域 af unix unix域 af ups...