send() - Unix 和 Linux 系統呼叫
廣告
名稱send、sendto、sendmsg - 在套接字上傳送訊息語法
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s, const void *buf, size_t len, int flags);
ssize_t sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int s, const struct msghdr *msg, int flags); 描述系統呼叫 send()、sendto() 和 sendmsg() 用於將訊息傳輸到另一個套接字。只有當套接字處於 已連線 狀態(以便知道預期的接收者)時,才能使用 send() 呼叫。send() 和 write() 之間的唯一區別是 flags 的存在。當 flags 引數為零時,send() 等效於 write()。此外,send(s,buf,len,flags) 等效於 sendto(s,buf,len,flags,NULL,0)。 引數 s 是傳送套接字的檔案描述符。 如果在連線模式(SOCK_STREAM、SOCK_SEQPACKET)套接字上使用 sendto(),則引數 to 和 tolen 將被忽略(並且當它們不為 NULL 和 0 時可能會返回錯誤 EISCONN),並且當套接字實際上未連線時會返回錯誤 ENOTCONN。否則,目標的地址由 to 給出,tolen 指定其大小。對於 sendmsg(),目標的地址由 msg.msg_name 給出,msg.msg_namelen 指定其大小。 對於 send() 和 sendto(),訊息位於 buf 中,長度為 len。對於 sendmsg(),訊息由陣列 msg.msg_iov 的元素指向。sendmsg() 呼叫還允許傳送輔助資料(也稱為控制資訊)。 如果訊息太長而無法透過底層協議原子地傳遞,則會返回錯誤 EMSGSIZE,並且不會傳輸訊息。 send() 中沒有隱含的傳遞失敗指示。本地檢測到的錯誤由返回值 -1 指示。 當訊息不適合套接字的傳送緩衝區時,send() 通常會阻塞,除非套接字已置於非阻塞 I/O 模式。在這種情況下,在非阻塞模式下它將返回 EAGAIN。可以使用 select(2) 呼叫來確定何時可以傳送更多資料。 flags 引數是以下標誌的按位 OR。
標籤 | 描述 |
MSG_CONFIRM(僅限 Linux 2.3+) | | 告訴鏈路層發生了轉發進度:您從另一端獲得了成功的回覆。如果鏈路層沒有收到此資訊,它將定期探測鄰居(例如,透過單播 ARP)。僅在 SOCK_DGRAM 和 SOCK_RAW 套接字上有效,目前僅在 IPv4 和 IPv6 上實現。有關詳細資訊,請參閱 arp(7)。 |
MSG_DONTROUTE | | 不要使用閘道器傳送資料包,僅傳送到直接連線網路上的主機。這通常僅由診斷或路由程式使用。這僅針對路由的協議族定義;資料包套接字沒有。 |
MSG_DONTWAIT | | 啟用非阻塞操作;如果操作將阻塞,則返回 EAGAIN(這也可以使用 O_NONBLOCK 與 F_SETFL fcntl(2) 啟用)。 |
MSG_EOR | | 終止記錄(當此概念受支援時,例如對於型別為 SOCK_SEQPACKET 的套接字)。 |
MSG_MORE(自 Linux 2.4.4 起) | | 呼叫者有更多資料要傳送。此標誌與 TCP 套接字一起使用以獲得與 TCP_CORK 套接字選項相同的效果(請參閱 tcp(7)),區別在於此標誌可以在每個呼叫基礎上設定。 自 Linux 2.6 起,此標誌也受 UDP 套接字支援,並通知核心將使用此標誌設定的所有傳送資料打包到單個數據報中,該資料報僅在執行未指定此標誌的呼叫時傳輸。(另請參閱 udp(7) 中描述的 UDP_CORK 套接字選項)。 |
MSG_NOSIGNAL | | 請求在流式套接字上發生錯誤時不要傳送 SIGPIPE,當另一端斷開連線時。EPIPE 錯誤仍然返回。 |
MSG_OOB | | 在支援此概念的套接字(例如型別為 SOCK_STREAM 的套接字)上傳送 帶外 資料;底層協議也必須支援 帶外 資料。 |
msghdr 結構的定義如下。有關其欄位的確切描述,請參閱 recv(2) 和以下內容。
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
socklen_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
|
您可以使用 msg_control 和 msg_controllen 成員傳送控制資訊。核心可以處理的最大控制緩衝區長度受 net.core.optmem_max sysctl 限制;請參閱 socket(7)。 返回值成功時,這些呼叫返回傳送的字元數。發生錯誤時,返回 -1,並且 errno 設定為適當的值。錯誤這些是套接字層生成的一些標準錯誤。其他錯誤可能會由底層協議模組生成和返回;請參閱它們各自的手冊頁。
標籤 | 描述 |
EACCES | (對於由路徑名標識的 Unix 域套接字)目標套接字檔案上拒絕寫入許可權,或者路徑字首中的一個目錄上拒絕搜尋許可權。(請參閱 path_resolution(2)。) |
EAGAIN 或 EWOULDBLOCK | | 套接字被標記為非阻塞,並且請求的操作將阻塞。 |
EBADF | 指定了無效的描述符。 |
ECONNRESET | | 連線被對等方重置。 |
EDESTADDRREQ | | 套接字不是連線模式,並且未設定對等方地址。 |
EFAULT | 為引數指定了無效的使用者空間地址。 |
EINTR | 在任何資料傳輸之前發生了訊號。 |
EINVAL | 傳遞了無效的引數。 |
EISCONN | | 連線模式套接字已連線,但指定了接收者。(現在要麼返回此錯誤,要麼忽略接收者規範)。 |
EMSGSIZE | | 套接字型別要求以原子方式傳送訊息,並且要傳送的訊息的大小使得這成為不可能。 |
ENOBUFS | | 網路介面的輸出佇列已滿。這通常表示介面已停止傳送,但也可能是由瞬態擁塞引起的。(通常,這不會在 Linux 中發生。當裝置佇列溢位時,資料包只是被靜默丟棄)。 |
ENOMEM | 沒有可用的記憶體。 |
ENOTCONN | | 套接字未連線,並且未給出目標。 |
ENOTSOCK | | 引數 s 不是套接字。 |
EOPNOTSUPP | | flags 引數中的一些位不適用於套接字型別。 |
EPIPE | 在面向連線的套接字上,本地端已關閉。在這種情況下,程序也將接收 SIGPIPE,除非設定了 MSG_NOSIGNAL。 |
符合標準4.4BSD、SVr4、POSIX.1-2001。這些函式調用出現在 4.2BSD 中。POSIX.1-2001 僅描述 MSG_OOB 和 MSG_EOR 標誌。MSG_CONFIRM 標誌是 Linux 擴充套件。 註釋上面給出的原型遵循 Single Unix Specification,就像 glibc2 一樣;flags 引數在 4.x BSD 中為 'int',但在 libc4 和 libc5 中為 'unsigned int';len 引數在 4.x BSD 和 libc4 中為 'int',但在 libc5 中為 'size_t';tolen 引數在 4.x BSD 和 libc4 和 libc5 中為 'int'。另請參閱 accept(2)。根據 POSIX.1-2001,msghdr 結構的 msg_controllen 欄位應型別化為 socklen_t,但 glibc 當前(2.4)將其型別化為 size_t。 錯誤Linux 可能會返回 EPIPE 而不是 ENOTCONN。另請參閱
廣告
|