socket - Linux 套接字
#include <sys/socket.h>
mysocket = socket(int socket_family, int
socket_type, int protocol);
本手冊頁介紹了 Linux
套接字的使用者介面.
這個 BSD
相容套接字是介於用
戶程序與核心網路協議棧之間的統一介面,
各協議模組屬於不同的
協議族 ,如
PF_INET,
PF_IPX,
PF_PACKET 和
套接字型別
,如
位元組流(SOCK_STREAM)
或
資料報(SOCK_DGRAM).
關於協議族和套接字型別請參考
socket(2).
使用者透過這些套接字函式傳送和接收包,
以及其他套接字操作.
詳細說明參看他們各自的手冊頁.
socket(2) 建立套接字,
connect(2)
與遠端套接字地址建立連線
bind(2)
把套接字和一個本地套接字地址繫結在一起(為套接字分配一個本地協議地址)
listen(2)
通知套接字接受新的連線
accept(2)
為新的已完成連接獲得新的描述字
socketpair(2)
返回兩個連線的匿名套接字(僅在某些本地族中才有實現,如
PF_UNIX)
send(2),
sendto(2), 和
sendmsg(2)
透過套接字傳送資料,而
recv(2),
recvfrom(2),
recvmsg(2)
從套接字接收資料.
poll(2) 和
select(2)
等待資料到來或準備好接收資料.
除此之外, 標準 I/O
操作如
write(2),
writev(2),
sendfile(2),
read(2), 和
readv(2)
也可用來讀入(接收)和寫出(傳送)資料.
getsockname(2)
用於獲得本地套接字地址
getpeername(2)
用於獲得遠端套接字地址.
getsockopt(2) 和
setsockopt(2)
用於設定或取得套接字或協議選項.
ioctl(2)
也可以用來設定或讀取一些其他選項.
close(2) 關閉套接字.
shutdown(2)
關閉全雙工套接字連線的一部分.
套接字不支援搜尋,也不支援呼叫
pread(2) 或
pwrite(2) 進行非 0
位置的操作. 可以用
fcntl(2). 設定
O_NONBLOCK
標誌來實現對套接字的非阻塞
I/O 操作
O_NONBLOCK 是從 accept
繼承來的,然後原來所有會阻塞的操作會返回
EAGAIN.
connect(2)
在此情況下返回
EINPROGRESS
錯誤. 使用者可以透過
poll(2) 或者
select(2)
等待各種事件.
I/O 事件 |
|
|
事件 |
輪詢標誌 |
發生事件 |
讀 |
POLLIN |
新資料到達. |
讀 |
POLLIN |
(對面向連線的套接字)建立連線成功 |
讀 |
POLLHUP |
另一端套接字發出斷開連線請求. |
讀 |
POLLHUP |
(僅對面向連線協議)套接字寫的時候連線斷開.
同時傳送 SIGPIPE. |
寫 |
POLLOUT |
套接字有充足的傳送緩衝區用於寫入新資料. |
讀/寫 |
POLLIN| POLLOUT |
發出的 connect (2) 結束. |
讀/寫 |
POLLERR |
產生一個非同步錯誤. |
讀/寫 |
POLLHUP |
對方已經單向關閉連線. |
例外 |
POLLPRI |
緊急資料到達.然後傳送
SIGURG. |
. |
|
|
. |
|
|
. |
|
|
. |
|
|
. |
|
|
. |
|
|
. |
|
|
另外一個的 poll/select
方法是讓核心用
SIGIO
訊號來通知應用程式.
要這麼用的話你必須用
fcntl(2)
設定套接字檔案描述符的
FASYNC 標誌,並用
sigaction(2).
給
SIGIO
訊號設定一個的有效訊號處理控制代碼.參看下面的
SIGNALS 的討論.
套接字選項可以用
setsockopt(2) 來設定,用
getsockopt(2)
讀取所有套接字級別設為
SOL_SOCKET
的套接字的套接字選項:
- SO_KEEPALIVE
- 允許在面向連線的套接字上傳送
keep-alive
訊息的功能.是一個布林整數.
- SO_OOBINLINE
- 如果開啟這個選項,帶外(Out-of-Band)資料可以直接放入接收資料流。
否則,只有接收時開啟
MSG_OOB 標誌,
才接收帶外資料.
-
SO_RCVLOWAT 和 SO_SNDLOWAT
- 宣告在開始向協議
(SO_SNDLOWAT)
或正在接收資料的使用者
(SO_RCVLOWAT).
傳遞資料之前緩衝區內的最小位元組數.
在 Linux
中這兩個值是不可改變的,
固定為 1 位元組.
可以用 getsockopt
用來讀取它們的值;
setsockopt 總是返回
ENOPROTOOPT.
-
SO_RCVTIMEO 和 SO_SNDTIMEO
- 傳送和接收時的超時設定,
並在超時時報錯. 在 Linux
中由 協議指定,
不能被讀寫.
它們的功能可用 alarm(2)
或者 setitimer(2). 來模擬.
- SO_BSDCOMPAT
- 允許 BSD 的 bug-to-bug 相容.
這一項只能在 UDP
協議模組中使用而
且今後將要取消.
如果允許的話, UDP
套接字接收到的 ICMP
錯誤將不
會被傳送至使用者程式.
Linux 2.0
中對於原始套接字也允許
BSD bug-to-bug
相容(報頭隨機改變,省略廣播標識),但在
Linux 2.2 中取消了這一項.
修改使用者程式的方式比較好.
- SO_PASSCRED
- 允許或關閉
SCM_CREDENTIALS
控制訊息的接收.
更多資訊參見 unix(7).
- SO_PEERCRED
- 返回連線至此套接字的外部程序的身份驗證.
只在 PF_UNIX
套接字中有用.參見
unix(7). 引數為 ucred
結構.只在 getsockopt.
中有效.
- SO_BINDTODEVICE
- 將此套接字繫結到一個特定的裝置上,
如“eth0”,
做為指定的介面名字傳遞.
如果名稱是空字串或此項長度為
0,
則套接字裝置繫結被取消.
過去的選項是一個變長的空零結尾的
介面名稱的字串,
其最大長度為 IFNAMSIZ.
如果一個套接字被繫結至一介面,
只有由這個特定介面接收的資訊包可以由此套接字處理.
- SO_DEBUG
- 允許套接字除錯.只對有
CAP_NET_ADMIN
功能或有效使用者標識為
0 的程序有效.
- SO_REUSEADDR
- 表示在一個 bind(2)
呼叫中對提供給它的地址使用的確認規則應該允許重複使用本地地址.
對於 PF_INET 套接字,
這表示該套接字可以繫結,
除非已有一個活躍的偵聽套
介面繫結到此地址上.
如果這個偵聽套接字和一個指定埠繫結為
INADDR_ANY 時,
它就不能再繫結到任何本地地址的此埠.
- SO_TYPE
- 按整數返回套接字型別(如
SOCK_STREAM) 只能透過
getsockopt 讀取.
- SO_DONTROUTE
- 不透過閘道器傳送,
只能傳送給直接連線的主機.可以透過在套接字的
send(2) 操作上設定
MSG_DONTROUTE
標誌來實現相同的效果.
其值為布林型整數的標識.
- SO_BROADCAST
- 設定或獲取廣播標識.
當選擇此選項時,
資料報套接字接收向
廣播地址傳送的資料包,
並且可以向廣播地址傳送資料包.
這一
選項對於面向流的套接字無效.
- SO_SNDBUF
- 設定或得到套接字傳送緩衝區的最大位元組數.
其預設值由 wmem_default sysctl
設定,最大允許值由
wmem_max sysctl 設定.
- SO_RCVBUF
- 設定或得到套接字接收緩衝區的最大位元組數。其預設值由
rmem_default
sysctl設定,最大允許值由
rmem_max sysctl 設定.
- SO_LINGER
- 設定或獲取 SO_LINGER
選項的值. 其引數為
linger 結構.
struct linger {
int l_onoff; /* 延時狀態(開啟/關閉) */
int l_linger; /* 延時多長時間 */
};
- 如果選擇此選項,
close(2) 或 shutdown(2)
將等到所有套接字裡排隊的訊息成功傳送或到達延遲時間後
才會返回. 否則,
呼叫將立即返回. 而 closing
操作將在後臺 進行.
如果套接字是 exit(2),
的一部分關閉時,
它總是在後臺延遲進行的.
- SO_PRIORITY
- 設定在此套接字傳送的所有包的協議定義優先權.
Linux
透過這一值來排列網路佇列:
根據所選裝置排隊規則,
具有更高優先權的包可以先被處理.對於
ip(7),
同時也設定了輸出包的
IP
服務型別(TOS)的域.
- SO_ERROR
- 取得並清除未解決的套接字錯誤.
只有在 getsockopt. 時有效.
是一個整數值.
當向一個已關閉(被本地或遠端終端)的面向聯接的套接字寫入時,
將向該寫入程序傳送
SIGPIPE 訊號,並返回
EPIPE
如果寫入命令聲明瞭
MSG_NOSIGNAL 標識時,
不會發出此訊號.
如果與
FIOCSETOWN fcntl 或
SIOCSPGRP ioctl
一起請求,那麼當發生
I/O 事件時發出
SIGIO
這樣我們就可以在訊號控制代碼裡使用
poll(2) 或
select(2)
找出發生事件的套接字.
另一種選擇(在 Linux 2.2
中)是用
F_SETSIG fcntl
設定一個實時訊號:
實時訊號的處理程式被呼叫時還會收到它的
siginfo_t 的
si_fd
區域中的檔案描述符.
更多資訊參見
fcntl(2)
在某些環境中(例如:多個程序訪問單個套接字),
引發
SIGIO
的東西在程序對訊號作出反應時可能已經消失了.
如果這樣的話,
程序應該再次等待,
因為 Linux
稍後會重發此訊號.
可以透過目錄
/proc/sys/net/core/*
下的檔案或者用
sysctl(2)
系統呼叫來訪問核心套接字的網路系統控制(sysctl)資訊.
- rmem_default
- 指明套接字接收緩衝區的預設位元組數.
- rmem_max
- 指明套接字接收緩衝區的最大位元組數,
使用者可以透過使用
SO_RCVBUF
套接字選項來設定此值.
- wmem_default
- 指明套接字傳送緩衝區的預設位元組數.
- wmem_max
- 指明發送緩衝區的最大位元組數,使用者可以透過使用套接字的
SO_SNDBUF
選項來設定它的值.
-
message_cost 和 message_burst
- 設定記號儲存桶過濾器,
在儲存桶中儲存一定數量的外部網路
事件導致的警告訊息.
- netdev_max_backlog
- 在全域性輸入佇列中包的最大數目.
- optmem_max
- 每個套接字的象
iovecs
這樣的輔助資料和使用者控制資料的最大長度.
以上的 IO
控制值可以透過
ioctl(2)
來訪問:
error = ioctl(ip_socket, ioctl_type, &value_result);
- SIOCGSTAMP
- 返回 timeval
型別的結構,其中包括有傳送給使用者的最後一個包接收時的時間戳。
被用來測量精確的 RTT
(round trip time) 時間. struct timeval.
結構說明請參考
setitimer(2)
- SIOCSPGRP
- 在非同步 IO
操作結束或者接收到緊急資料時,用來設定程序或程序組,
向它(它們)傳送
SIGIO 或者 SIGURG 訊號,
引數為指向 pid_t.
型別的指標。如果引數為正,則傳送訊號到相應的程序。如果引數為
負,則傳送訊號到此引數絕對值
id
所屬的程序組的所有程序。
如果它沒有 CAP_KILL
功能或者它的有效 UID
不是 0,
程序只能選擇它自己或自己的程序組來
接收訊號.
- FIOASYNC
- 改變 O_ASYNC
標誌來開啟或者關閉套接字的非同步
IO
模式。非同步IO模式指的是:當
新的 I/O
事件發生時,將發出
SIGIO 訊號或者用 F_SETSIG
設定的訊號.
- 引數為整形布林量.
- SIOCGPGRP
- 獲得當前接收
SIGIO 或者 SIGURG
訊號的程序或者程序組,
如果兩個訊號都沒有設定,
則為 0.
有效的 fcntl:
- FIOCGETOWN
- 與 IO 控制中的 SIOCGPGRP
相同.
- FIOCSETOWN
- 與 IO 控制中的 SIOCSPGRP
相同.
Linux
假設有一半的傳送/接收緩衝區是用來處理核心結構,
因此,
系統控制的緩衝區是網路可訪問的緩衝區的兩倍.
CONFIG_FILTER 沒有介紹
SO_ATTACH_FILTER
和
SO_DETACH_FILTER 套接字選項.
在 libpcap
庫有此介面的說明
SO_BINDTODEVICE 在 Linux 2.0.30 中引入.
SO_PASSCRED 是在 Linux 2.2
中引入的新選項. sysctl
是在 Linux 2.2.
中引入的新概念。
本手冊頁由 Andi Kleen 編寫.
socket(2),
ip(7),
setsockopt(2),
getsockopt(2),
packet(7),
ddp(7)
liguoping <[email protected]>
2000/11/06
http://cmpp.linuxforum.net
本頁面中文版由中文 man
手冊頁計劃提供。
中文 man 手冊頁計劃:
https://github.com/man-pages-zh/manpages-zh