send, sendto, sendmsg -
從套接字傳送訊息
#include <sys/types.h>
#include <sys/socket.h>
int send(int s, const void *msg, size_t
len, int flags);
int sendto(int s, const void *msg, size_t
len, int flags, const struct sockaddr
*to, socklen_t tolen);
int sendmsg(int s, const struct msghdr *msg,
int flags);
Send,
sendto, 和
sendmsg
用於向另一個套接字傳遞訊息.
Send
僅僅用於連線套接字,而
sendto 和
sendmsg
可用於任何情況下.
目標地址用
to 指定,
tolen
定義其長度.訊息的長度用
len 指定.
如果訊息太長不能透過下層協議,函式將返回
EMSGSIZE
錯誤,訊息也不會被送出.
在資料傳送過程中所產生的錯誤不會返回給
send.
如果發生本地錯誤,則返回-1.
當要傳送的訊息長度大於套接字當前可用緩衝區時,
send
將阻塞,除非在套接字上設定了非阻塞式輸入輸出模式.
對於非阻塞模式,這種情況下將返回
EAGAIN 錯誤. The 系統呼叫
select(2)
可以用來檢測何時可以傳送更多的資料.
引數
flags
是一個標誌字,可以包含下列標誌:
- 對於支援帶外資料的套接字,
-
MSG_OOB 將送出 out-of-band
(帶外)資料(比如, SOCK_STREAM
型別的套接字);
下層協議也必須支援.
帶外 資料.
- MSG_DONTROUTE
- 在送出分組時不使用閘道器.只有直接連線在網路上的主機
才能接收到資料.這個標誌通常僅用於診斷和路由程式.
可路由的協議族才能使用這個標誌;包套接字不可以.
- MSG_DONTWAIT
- 使用非阻塞式操作;如果操作需要阻塞,將返回
EAGAIN 錯誤(也可以用
F_SETFL fcntl(2) 設定 O_NONBLOCK
實現這個功能.)
- MSG_NOSIGNAL
- 當流式套接字的另一端中斷連線時不傳送
SIGPIPE 訊號,但仍然返回
EPIPE 錯誤.
-
MSG_CONFIRM (僅用於Linux
2.3以上版本)
- 通知鏈路層發生了轉發過程:得到了另一端的成功應答.
如果鏈路層沒有收到通知,它將按照常規探測網路上的相鄰
主機(比如透過免費arp).
只能用於 SOCK_DGRAM 和
SOCK_RAW
型別的套接字,且僅對IPv4和IPv6有效.詳情參見
arp(7)
結構體
msghdr
的定義如下.詳情參見
recv(2) 和下文.
struct msghdr {
void * msg_name; /*地址選項*/
socklen_t msg_namelen; /*地址長度*/
struct iovec * msg_iov; /*訊息陣列*/
size_t msg_iovlen; /*msg_iov中的元素個數*/
void * msg_control; /*輔助資訊,見下文*/
socklen_t msg_controllen; /*輔助資料緩衝區長度*/
int msg_flags; /*接收訊息標誌*/
};
可以使用
msg_control 和
msg_controllen
成員傳送任何控制資訊.核心所能處理的最大控制訊息緩衝區長度由
net.core.optmem_max
sysctl對每個套接字進行限定;參見
socket(7).
成功時返回傳送的字元個數,否則返回-1.
其中一些是套接字層產生的標準錯誤.其他的是下層協議模組產生的;參見
各自的man手冊.
- EBADF
- 指定了非法描述符.
- ENOTSOCK
- 引數 s
不是一個套接字.
- EFAULT
- 引數指定的使用者地址空間非法.
- EMSGSIZE
- 訊息長度越界.
-
EAGAIN或者EWOULDBLOCK
- 套接字設定為非阻塞式,但所請求的操作需要阻塞.
- ENOBUFS
- 網路介面輸出佇列已滿.這通常表明介面已停止傳送,也有可能是
暫時性的擁擠(這不會發生在linux下,當裝置佇列溢位時資料報
只是被簡單丟棄.
- EINTR
- 接收到訊號.
- ENOMEM
- 沒有可用記憶體.
- EINVAL
- 傳遞的引數非法.
- EPIPE
- 連線套接字的本地端已關閉.這種情況下程序還會接收到
SIGPIPE 訊號,除非設定了
MSG_NOSIGNAL
4.4BSD,SVr4,POSIX1003.1g草案(這些系統呼叫首次出現於4.2BSD).
MSG_CONFIRM
是Linux所做的擴充套件.
上面給出的函式原型遵循Single
Unix Specification, glibc2也是這麼做的;
flags
引數在BSD4.*中是`int',但在libc4和libc5中是`unsigned
int'; 引數
len
在BSD4.*和libc4中是`int',但在libc5中是'size_t';
引數
tolen
在BSD4.*,libc4和libc5中都是`int'.
參見
accept(2).
fcntl(2),
recv(2),
select(2),
getsockopt(2),
sendfile(2),
socket(2),
write(2),
socket(7),
ip(7),
tcp(7),
udp(7)
byeyear <[email protected] >
2002.02.27
http://cmpp.linuxforum.net
本頁面中文版由中文 man
手冊頁計劃提供。
中文 man 手冊頁計劃:
https://github.com/man-pages-zh/manpages-zh