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 | 在面向連線的套接字上,本地端已關閉。在這種情況下,除非設定了MSG_NOSIGNAL,否則程序也將接收SIGPIPE。 |
符合標準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。參見
廣告
|