send,recv,sendto,recvfrom 用法

send函數 服務器

int send( SOCKET s,    const char FAR *buf,    int len,    int flags ); 網絡

不管是客戶仍是服務器應用程序都用send函數來向TCP鏈接的另外一端發送數據。socket

客戶程序通常用send函數向服務器發送請求,而服務器則一般用send函數來向客戶程序發送應答。函數

該函數的第一個參數指定發送端套接字描述符;spa

第二個參數指明一個存放應用程序要發送數據的緩衝區;進程

第三個參數指明實際要發送的數據的字節數;原型

第四個參數通常置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的發送緩衝區的剩餘空間裏)。若是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信號,進程對該信號的默認處理是進程終止。

 

recv函數
int recv( SOCKET s,   char FAR *buf,    int len,   int flags   );  

不管是客戶仍是服務器應用程序都用recv函數從TCP鏈接的另外一端接收數據。

該函數的第一個參數指定接收端套接字描述符;

第二個參數指明一個緩衝區,該緩衝區用來存放recv函數接收到的數據;

第三個參數指明buf的長度;

第四個參數通常置0。

這裏只描述同步Socket的recv函數的執行流程。當應用程序調用recv函數時,recv先等待s的發送緩衝 中的數據被協議傳送完畢,若是協議在傳送s的發送緩衝中的數據時出現網絡錯誤,那麼recv函數返回SOCKET_ERROR,若是s的發送緩衝中沒有數 據或者數據被協議成功發送完畢後,recv先檢查套接字s的接收緩衝區,若是s接收緩衝區中沒有數據或者協議正在接收數據,那麼recv就一直等待,只到 協議把數據接收完畢。當協議把數據接收完畢,recv函數就把s的接收緩衝中的數據copy到buf中(注意協議接收到的數據可能大於buf的長度,因此 在這種狀況下要調用幾回recv函數才能把s的接收緩衝中的數據copy完。recv函數僅僅是copy數據,真正的接收數據是協議來完成的),recv 函數返回其實際copy的字節數。若是recv在copy時出錯,那麼它返回SOCKET_ERROR;若是recv函數在等待協議接收數據時網絡中斷 了,那麼它返回0。

注意:在Unix系統下,若是recv函數在等待協議接收數據時網絡斷開了,那麼調用recv的進程會接收到一個SIGPIPE信號,進程對該信號的默認處理是進程終止。

 

sendto和recvfrom通常用於UDP協議中,可是若是在TCP中connect函數調用後也能夠用.

 

sendto()和recvfrom()——利用數據報方式進行數據傳輸    在無鏈接的數據報socket方式下,因爲本地socket並無與遠端機器創建鏈接,因此在發送數據時應指明目的地址,sendto()函數原型爲:    int sendto(int sockfd, const void *msg,int len unsigned int flags, const struct sockaddr *to, int tolen);    該函數比send()函數多了兩個參數,to表示目地機的IP地址和端口號信息,而tolen經常被賦值爲sizeof (struct sockaddr)。Sendto 函數也返回實際發送的數據字節長度或在出現發送錯誤時返回-1。    recvfrom()函數原型爲:    int recvfrom(int sockfd,void *buf,int len,unsigned int lags,struct sockaddr *from,int *fromlen);     from是一個struct sockaddr類型的變量,該變量保存源機的IP地址及端口號。fromlen常置爲sizeof (struct sockaddr)。當recvfrom()返回時,fromlen包含實際存入from中的數據字節數。Recvfrom()函數返回接收到的字節數或 當出現錯誤時返回-1,並置相應的errno。    應注意的一點是,當你對於數據報socket調用了connect()函數時,你也能夠利 用send()和recv()進行數據傳輸,但該socket仍然是數據報socket,而且利用傳輸層的UDP服務。但在發送或接收數據報時,內核會自 動爲之加上目地和源地址信息。

相關文章
相關標籤/搜索