send, sendto, sendmsg - send a message on a socket
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、做網(wǎng)站、永濟(jì)網(wǎng)絡(luò)推廣、小程序定制開發(fā)、永濟(jì)網(wǎng)絡(luò)營銷、永濟(jì)企業(yè)策劃、永濟(jì)品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供永濟(jì)建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com
系統(tǒng)調(diào)用 send()、sendto() 和 sendmsg() 用于將消息傳輸?shù)搅硪粋€(gè)套接字。
僅當(dāng)套接字處于連接狀態(tài)時(shí)才可以使用 send() 調(diào)用(以便知道預(yù)期的接收者, 也就是說send()僅僅用于數(shù)據(jù)流類型的數(shù)據(jù)發(fā)送 ,對于TCP,服務(wù)端和客戶端都可以使用send/recv;但是對于UDP,只能是客戶端使用send/recv,服務(wù)端只能使用sendto/recvfrom,因?yàn)榭蛻舳耸沁M(jìn)行了connect操作知道要發(fā)送和接受的地址)。send() 和 write(2) 之間的唯一區(qū)別是存在 flags 參數(shù)。此外,
send(sockfd, buf, len, flags);
等價(jià)于
sendto(sockfd, buf, len, flags, NULL, 0);
參數(shù) sockfd 是發(fā)送者套接字的文件描述符。
如果在連接模式的套接字(即套接字類型為SOCK_STREAM、SOCK_SEQPACKET)上使用 sendto(),則參數(shù) dest_addr 和 addrlen 將被忽略(當(dāng)它們不是NULL和0時(shí)可能返回錯(cuò)誤EISCONN),若套接字沒有實(shí)際連接(還沒有三次握手建立連接)將返回錯(cuò)誤ENOTCONN。 否則,目標(biāo)地址由 dest_addr 給出, addrlen 指定其大小。 對于 sendmsg(),目標(biāo)地址由 msg.msg_name 給出, msg.msg_namelen 指定其大小。
對于 send() 和 sendto(),消息位于 buf 中,長度為 len 。 對于sendmsg(),消息存放于 msg.msg_iov 元素指向 數(shù)組數(shù)據(jù)區(qū) (見下)中。 sendmsg() 調(diào)用還允許發(fā)送輔助數(shù)據(jù)(也稱為控制信息) 。
如果消息太長而無法通過底層協(xié)議原子傳遞( too long to pass atomically through the underlying protocol ),則返回錯(cuò)誤 EMSGSIZE,并且不會(huì)傳輸消息。
No indication of failure to deliver is implicit in a send(). Locally detected errors are indicated by a return value of -1.
當(dāng)消息不適合套接字的發(fā)送緩沖區(qū)時(shí),send() 通常會(huì)阻塞,除非套接字已置于非阻塞 I/O 模式。 在這種情況下,在非阻塞模式下它會(huì)失敗并顯示錯(cuò)誤 EAGAIN 或 EWOULDBLOCK。 select(2) 調(diào)用可用于確定何時(shí)可以發(fā)送更多數(shù)據(jù) 。
上面的的描述還是很籠統(tǒng)的,以TCP為例,按我的理解,我認(rèn)為只要發(fā)送緩沖區(qū)有空閑位置,且此時(shí)協(xié)議棧沒有向網(wǎng)絡(luò)發(fā)送數(shù)據(jù),那么就可以寫入,對于阻塞模式,直到所有數(shù)據(jù)寫入到緩沖區(qū),就會(huì)返回,否則一直阻塞,對于非阻塞模式,是有一個(gè)超時(shí)時(shí)間的,這個(gè)由 SO_SNDTIMEO 選項(xiàng)控制,詳細(xì)見 socket(7) ,如果當(dāng)前有空閑位置可以發(fā)即當(dāng)前可寫入,那么就寫入到緩沖區(qū),知道超時(shí)之前寫入多少算多少,然后返回成功寫入的字節(jié)數(shù),如果超時(shí)時(shí)任何數(shù)據(jù)都沒寫出去,或者當(dāng)前就是不可寫入,那么返回-1 ,并設(shè)置errno為 EAGAIN 或 EWOULDBLOCK。
The flags argument is the bitwise OR of zero or more of the following flags.
sendmsg() 使用的 msghdr 結(jié)構(gòu)的定義如下:
對于未連接的套接字 msg_name 指定數(shù)據(jù)報(bào)的目標(biāo)地址,它指向一個(gè)包含地址的緩沖區(qū); msg_namelen 字段應(yīng)設(shè)置為地址的大小。 對于連接的套接字,這些字段應(yīng)分別指定為 NULL 和 0。 這里的未連接指的是數(shù)據(jù)報(bào)協(xié)議,連接指的是數(shù)據(jù)流協(xié)議
The msg_iov and msg_iovlen fields specify scatter-gather locations, as for writev(2).
msg_iov是一個(gè)buffer數(shù)組:
使用 msg_control 和 msg_controllen 成員發(fā)送控制信息(輔助數(shù)據(jù))。 內(nèi)核可以處理的每個(gè)套接字最大控制緩沖區(qū)長度由 /proc/sys/net/core/optmem_max 中的值限制; 見 socket(7) 。 有關(guān)在各種套接字域中使用輔助數(shù)據(jù)的更多信息,請參閱 unix(7) 和 ip(7)。
msg_flags 字段被忽略。
成功時(shí),返回成功發(fā)送的字節(jié)數(shù),這個(gè)字節(jié)數(shù)并不一定和我們的緩沖區(qū)大小相同 。 出錯(cuò)時(shí),返回 -1,并設(shè)置 errno 以指示錯(cuò)誤。
這些是套接字層生成的一些標(biāo)準(zhǔn)錯(cuò)誤。 底層協(xié)議模塊可能會(huì)產(chǎn)生和返回額外的錯(cuò)誤; 請參閱它們各自的手冊頁。
4.4BSD, SVr4, POSIX.1-2001. These interfaces first appeared in 4.2BSD.
POSIX.1-2001 describes only the MSG_OOB and MSG_EOR flags. POSIX.1-2008 adds a specification of MSG_NOSIGNAL. The MSG_CONFIRM flag is a Linux extension.
根據(jù) POSIX.1-2001,msghdr 結(jié)構(gòu)的 msg_controllen 字段應(yīng)該是 socklen_t 類型,而 msg_iovlen 字段應(yīng)該是 int 類型,但是 glibc 目前將兩者都視為 size_t。
有關(guān)可用于在單個(gè)調(diào)用中傳輸多個(gè)數(shù)據(jù)報(bào)的 Linux 特定系統(tǒng)調(diào)用的信息,請參閱 sendmmsg(2)。
Linux may return EPIPE instead of ENOTCONN.
getaddrinfo(3) 中顯示了使用 send() 的示例。
功能描述:
發(fā)送消息,send只可用于基于連接的套接字,send 和 write唯一的不同點(diǎn)是標(biāo)志的存在,當(dāng)標(biāo)志為0時(shí),send等同于write。sendto 和 sendmsg既可用于無連接的套接字,也可用于基于連接的套接字。除了套接字設(shè)置為非阻塞模式,調(diào)用將會(huì)阻塞直到數(shù)據(jù)被發(fā)送完。
用法:
#include?sys/types.h
#include?sys/socket.h
ssize_t?send(int?sock,?const?void?*buf,?size_t?len,?int?flags);
ssize_t?sendto(int?sock,?const?void?*buf,?size_t?len,?int?flags,?const?struct?sockaddr?*to,?socklen_t?tolen);
ssize_t?sendmsg(int?sock,?const?struct?msghdr?*msg,?int?flags);
參數(shù):??
sock:索引將要從其發(fā)送數(shù)據(jù)的套接字。
buf:指向?qū)⒁l(fā)送數(shù)據(jù)的緩沖區(qū)。
len:以上緩沖區(qū)的長度。
flags:是以下零個(gè)或者多個(gè)標(biāo)志的組合體,可通過or操作連在一起
MSG_DONTROUTE:不要使用網(wǎng)關(guān)來發(fā)送封包,只發(fā)送到直接聯(lián)網(wǎng)的主機(jī)。這個(gè)標(biāo)志主要用于診斷或者路由程序。
MSG_DONTWAIT:操作不會(huì)被阻塞。
MSG_EOR:終止一個(gè)記錄。
MSG_MORE:調(diào)用者有更多的數(shù)據(jù)需要發(fā)送。
MSG_NOSIGNAL:當(dāng)另一端終止連接時(shí),請求在基于流的錯(cuò)誤套接字上不要發(fā)送SIGPIPE信號。
MSG_OOB:發(fā)送out-of-band數(shù)據(jù)(需要優(yōu)先處理的數(shù)據(jù)),同時(shí)現(xiàn)行協(xié)議必須支持此種操作。
to:指向存放接收端地址的區(qū)域,可以為NULL。
tolen:以上內(nèi)存區(qū)的長度,可以為0。
linuxsend返回值為9:
linuxsend返回值為9因?yàn)镺S Linux Mint 14.客戶端在啟動(dòng)時(shí)向服務(wù)器發(fā)送請求以獲取一些會(huì)話參數(shù),包括usec中的超時(shí) . 客戶端打開一個(gè)套接字并設(shè)置一個(gè)默認(rèn)超時(shí)值,以便在recvfrom上不被無限制地阻塞,然后發(fā)送對這些參數(shù)的請求,關(guān)閉所述套接字,重新打開設(shè)置新超時(shí)值的套接字,最后詢問用戶用于命令 .
參數(shù)請求由子函數(shù)處理,該子函數(shù)除了其他之外還獲得指向客戶端套接字的指針,因此如果新的sockfd是不同的數(shù)字,則主函數(shù)也將能夠引用新的套接字 . (返回值用作檢查值,零或非零)