send() - Unix,Linux系統呼叫 - 技術教學
Tutorials Point


  Unix入門
  Unix Shell程式設計
  高階Unix
  Unix有用參考
  Unix有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考資料     討論論壇     關於TP  

send() - Unix,Linux系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

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(),則引數totolen將被忽略(當它們不為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_DGRAMSOCK_RAW套接字上有效,目前僅針對IPv4和IPv6實現。有關詳細資訊,請參閱arp(7)。
MSG_DONTROUTE
 不要使用閘道器傳送資料包,只發送到直接連線的網路上的主機。這通常僅由診斷或路由程式使用。這僅針對路由的協議族定義;資料包套接字沒有。
MSG_DONTWAIT
 啟用非阻塞操作;如果操作會阻塞,則返回EAGAIN(這也可以使用O_NONBLOCKF_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_controlmsg_controllen成員傳送控制資訊。核心可以處理的最大控制緩衝區長度受net.core.optmem_max sysctl每個套接字限制;參見socket(7)。

返回值

成功時,這些呼叫返回傳送的字元數。出錯時,返回-1,並適當地設定errno

錯誤

這些是由套接字層生成的某些標準錯誤。其他錯誤可能會由底層協議模組生成並返回;請參閱它們各自的手冊頁。
標籤描述
EACCES (對於由路徑名標識的Unix域套接字)目標套接字檔案上的寫許可權被拒絕,或者路徑字首之一的目錄上的搜尋許可權被拒絕。(參見path_resolution(2)。)
EAGAINEWOULDBLOCK
 套接字被標記為非阻塞,並且請求的操作將阻塞。
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_OOBMSG_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。

參見



previous next Printer Friendly

廣告


  

廣告



廣告
© . All rights reserved.