複製鏈接
請複製以下鏈接發送給好友

send()

鎖定
send()是一個計算機函數,功能是向一個已經連接的socket發送數據,如果無錯誤,返回值為所發送數據的總數,否則返回SOCKET_ERROR。
中文名
外文名
send
buf
包含待發送數據的緩衝區。
len
緩衝區中數據的長度。
flags
調用執行方式。

send()介紹

int send( SOCKET s, const char FAR *buf, int len, int flags );
不論是客户還是服務器應用程序都用send函數來向TCP連接的另一端發送數據。
客户程序一般用send函數向服務器發送請求,而服務器則通常用send函數來向客户程序發送應答。
(1)第一個參數指定發送端套接字描述符;
(2)第二個參數指明一個存放應用程序要發送數據的緩衝區;
(3)第三個參數指明實際要發送的數據的字節數;
(4)第四個參數一般置0。
這裏只描述同步Socket的send函數的執行流程。當調用該函數時,send先比較待發送數據的長度len和套接字s的發送緩衝的長度, 如果len大於s的發送緩衝區的長度,該函數返回SOCKET_ERROR;如果len小於或者等於s的發送緩衝區的長度,那麼send先檢查協議是否正在發送s的發送緩衝中的數據,如果是就等待協議把數據發送完,如果協議還沒有開始發送s的發送緩衝中的數據或者s的發送緩衝中沒有數據,那麼send就比較s的發送緩衝區的剩餘空間和len,如果len大於剩餘空間大小send就一直等待協議把s的發送緩衝中的數據發送完,如果len小於剩餘空間大小send就僅僅把buf中的數據copy到剩餘空間裏(注意並不是send把s的發送緩衝中的數據傳到連接的另一端的,而是協議的,send僅僅是把buf中的數據copy到s的發送緩衝區的剩餘空間裏) [1] 
如果send函數copy數據成功,就返回實際copy的字節數,如果send在copy數據時出現錯誤,那麼send就返回SOCKET_ERROR;如果send在等待協議傳送數據時網絡斷開的話,那麼send函數也返回SOCKET_ERROR。
要注意send函數把buf中的數據成功copy到s的發送緩衝的剩餘空間裏後它就返回了,但是此時這些數據並不一定馬上被傳到連接的另一端。如果協議在後續的傳送過程中出現網絡錯誤的話,那麼下一個Socket函數就會返回SOCKET_ERROR。(每一個除send外的Socket函數在執行的最開始總要先等待套接字的發送緩衝中的數據被協議傳送完畢才能繼續,如果在等待時出現網絡錯誤,那麼該Socket函數就返回SOCKET_ERROR)。
注意:在Unix系統下,如果send在等待協議傳送數據時網絡斷開的話,調用send的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。

send()簡述

向一個已連接的套接口發送數據。
#include <winsock.h>
int PASCAL FAR send( SOCKET s, const char FAR* buf, int len, int flags);
s:一個用於標識已連接套接口的描述字。
buf:包含待發送數據的緩衝區
len:緩衝區中數據的長度。
flags:調用執行方式。
linux下函數
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

send()註釋

send()適用於已連接的數據包或流式套接口發送數據。對於數據報類套接口,必需注意發送數據長度不應超過通訊子網的IP包最大長度。IP包最大長度在WSAStartup()調用返回的WSAData的iMaxUdpDg元素中。如果數據太長無法自動通過下層協議,則返回WSAEMSGSIZE錯誤,數據不會被髮送。
請注意成功地完成send()調用並不意味着數據傳送到達。
如果傳送系統的緩衝區空間不夠保存需傳送的數據,除非套接口處於非阻塞I/O方式,否則send()將阻塞。對於非阻塞SOCK_STREAM類型的套接口,實際寫的數據數目可能在1到所需大小之間,其值取決於本地和遠端主機的緩衝區大小。可用select()調用來確定何時能夠進一步發送數據。
在相關套接口的選項之上,還可通過標誌位flag來影響函數的執行方式。也就是説,本函數的語義既取決於套接口的選項也取決於標誌位。後者由以下一些值組成:

send()值意義

MSG_DONTROUTE 指明數據不選徑。一個WINDOWS套接口供應商可以忽略此標誌;MSG_OOB 發送帶外數據(僅適用於SOCK_STREAM;)。

send()返回值

若無錯誤發生,send()返回所發送數據的總數(請注意這個數字可能小於len中所規定的大小)。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼
錯誤代碼:
WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。
WSAEACESS:要求地址為廣播地址,但相關標誌未能正確設置。
WSAEINTR:通過一個WSACancelBlockingCall()來取消一個(阻塞的)調用。
WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。
WSAEFAULT:buf參數不在用户地址空間中的有效位置。
WSAENETRESET:由於WINDOWS套接口實現放棄了連接,故該連接必需被複位。
WSAENOBUFS:WINDOWS套接口實現報告一個緩衝區死鎖
WSAENOTCONN:套接口未被連接。
WSAENOTSOCK:描述字不是一個套接口。
WSAEOPNOTSUPP:已設置了MSG_OOB,但套接口非SOCK_STREAM類型。
WSAESHUTDOWN:套接口已被關閉。一個套接口以1或2的how參數調用shutdown()關閉後,無法再用send()函數。
WSAEWOULDBLOCK:
WSAEMSGSIZE:套接口為SOCK_DGRAM類型,且數據報大於WINDOWS套接口實現所支持的最大值。
WSAEINVAL:套接口未用bind()捆綁。
WSAECONNABORTED:由於超時或其他原因引起虛電路的中斷。
WSAECONNRESET:虛電路被遠端復位。
參見:
參考資料
  • 1.    王衞. 功能強大的SendMessage函數[J]. 電腦愛好者, 1999(10):53-54.
  • 2.    winsock.h  .開源中國社區[引用日期2013-09-07]