-
recvfrom()
鎖定
recvfrom()是一個計算機函數,用於從(已連接)套接口上接收數據,並捕獲數據發送源的地址。
- 中文名
- recvfrom()
- 作 用
- 接收一個數據報並保存源地址
- 類 型
- socket
- 支持協議
- UDP/TCP
recvfrom()函數簡介
接收一個數據報並保存源地址。(這裏是windows中的頭文件,Linux的用法在下面的那個實例)
#include <winsock.h>
int PASCAL FAR recvfrom( SOCKET s, char FAR* buf, int len, int flags,struct sockaddr FAR* from, int FAR* fromlen);
s:標識一個已連接套接口的描述字。
buf:接收數據緩衝區。
len:緩衝區長度。
flags:調用操作方式。
from:(可選)指針,指向裝有源地址的緩衝區。
fromlen:(可選)指針,指向from緩衝區長度值。
recvfrom()註釋
對於SOCK_STREAM類型的套接口,最多可接收緩衝區大小個數據。如果套接口被設置為線內接收帶外數據(選項為SO_OOBINLINE),且有帶外數據未讀入,則返回帶外數據。應用程序可通過調用ioctlsocket的SOCATMARK命令來確定是否有帶外數據待讀入。對於SOCK_STREAM類型套接口,忽略from和fromlen參數。
對於數據報類套接口,隊列中第一個數據報中的數據被解包,但最多不超過緩衝區的大小。如果數據報大於緩衝區,那麼緩衝區中只有數據報的前面部分,其他的數據都丟失了,並且recvfrom函數返回WSAEMSGSIZE錯誤。
若from非零,且套接口為SOCK_DGRAM類型,則發送數據源的地址被複制到相應的sockaddr結構中。fromlen所指向的值初始化時為這個結構的大小,當調用返回時按實際地址所佔的空間進行修改。
如果沒有數據待讀,那麼除非是非阻塞模式,不然的話套接口將一直等待數據的到來,此時將返回SOCKET_ERROR錯誤,錯誤代碼是WSAEWOULDBLOCK。用select或WSAAsynSelect可以獲知何時數據到達。
如果套接口為SOCK_STREAM類型,並且遠端“優雅”地中止了連接,那麼recvfrom一個數據也不讀取,立即返回。如果立即被強制中止,那麼recv將以WSAECONNRESET錯誤失敗返回。
在套接口的所設選項之上,還可用標誌位flag來影響函數的執行方式。也就是説,本函數的語義既取決於套接口選項,也取決於標誌位參數。標誌位可取下列值:
值 意義
MSG_PEEK 查看當前數據。數據將被複制到緩衝區中,但並不從輸入隊列中刪除。
MSG_OOB 處理帶外數據(參見2.2.3節具體討論)。
返回值:
若無錯誤發生,recvfrom返回讀入的字節數。如果連接已中止,返回0。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError獲取相應錯誤代碼。
錯誤代碼:
WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup。
WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。
WSAEFAULT:fromlen參數非法;from緩衝區大小無法裝入端地址。
WSAEINTR:阻塞進程被WSACancelBlockingCall取消。
WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。
WSAEINVAL:套接口未用bind進行捆綁。
WSAENOTCONN:套接口未連接(僅適用於SOCK_STREAM類型)。
WSAENOTSOCK:描述字不是一個套接口。
WSAEOPNOTSUPP:指定了MSG_OOB,但套接口不是SOCK_STREAM類型的。
WSAESHUTDOWN:套接口已被關閉。當一個套接口以0或2的how參數調用shutdown關閉後,無法再用recv接收數據。
WSAEWOULDBLOCK:套接口標識為非阻塞模式,但接收操作會產生阻塞。
WSAEMSGSIZE:數據報太大無法全部裝入緩衝區,故被剪切。
WSAECONNABORTED:由於超時或其他原因,虛電路失效。
WSAECONNRESET:遠端強制中止了虛電路。
參見:
recv, send, socket, WSAAsyncSelect.
recvfrom()詳細介紹
recvfrom recvfrom函數(經socket接收數據):
函數原型:int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);
相關函數 recv,recvmsg,send,sendto,socket
函數説明:recv用來接收遠程主機經指定的socket傳來的數據,並把數據傳到由參數buf指向的內存空間,參數len為可接收數據的最大長度.參數flags一般設0,其他數值定義參考recv.參數from用來指定欲傳送的網絡地址,結構sockaddr請參考bind函數.參數fromlen為sockaddr的結構長度.
返回值:成功則返回接收到的字符數,失敗返回-1.
錯誤代碼
EBADF 參數s非合法的socket處理代碼
EFAULT 參數中有一指針指向無法存取的內存空間。
ENOTSOCK 參數s為一文件描述詞,非socket。
EINTR 被信號所中斷。
EAGAIN 此動作會令進程阻斷,但參數s的socket為不可阻斷。
ENOBUFS 系統的緩衝內存不足
ENOMEM 核心內存不足
EINVAL 傳給系統調用的參數不正確。
範例
/*利用socket的UDP client
此程序會連線UDP server,並將鍵盤輸入的字符串傳給server。
UDP server 範例請參考sendto。
*/ #include<sys/stat.h> #include<fcntl.h> #include<unistd.h> #include<sys/typs.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #define PORT 2345 #define SERVER_IP “127.0.0.1” main int s,len; struct sockaddr_in addr; int addr_len =sizeof(struct sockaddr_in); char buffer[256]; /* 建立socket*/ if(s = socket(AF_INET,SOCK_DGRAM,0)<0){ perror(“socket”); exit(1); /* 填寫sockaddr_in*/ bzero(&addr,sizeof(addr); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(SERVER_IP); while(1) bzero(buffer,sizeof(buffer); /* 從標準輸入設備取得字符串*/ len =read(STDIN_FILENO,buffer,sizeof(buffer); /* 將字符串傳送給server端*/ sendto(s,buffer,len,0,&addr,addr_len; /* 接收server端返回的字符串*/ len = recvfrom(s,buffer,sizeof(buffer),0,&addr,&addr_len; printf(“receive: %s”,buffer; 執行 (先執行udp server 再執行udp client) hello /*從鍵盤輸入字符串*/ receive: hello /*server端返回來的字符串*/
recvfrom()其他函數比較
與recv函數的比較:UDP使用recvfrom函數接收數據,他類似於標準的read,但是在recvfrom函數中要指明目的地址。從套接字上接收一個消息。對於recvfrom ,可同時應用於面向連接的和無連接的套接字。recv一般只用在面向連接的套接字,幾乎等同於recvfrom,只要將recvfrom的第五個參數設置NULL。不管是recv還是recvfrom,都有兩種模式,阻塞和非阻塞,可以通過ioctl函數來設置。阻塞模式是一直等待直到有數據到達,非阻塞模式是立即返回,需要通過消息,異步事件等來查詢完成狀態。
recvfrom()注意事項
第三個參數:len的值不能小於發送端的數據長度,否則會出現函數的返回結果(接收長度)為-1,而第二個參數buf 卻有數據的現象。
- 詞條統計
-
- 瀏覽次數:次
- 編輯次數:25次歷史版本
- 最近更新: 张中2014