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

recvfrom

鎖定
recvfrom函數(經socket接收數據):
函數原型:ssize_t recvfrom(int sockfd,void *buf,size_t len,unsigned int flags, struct sockaddr *from,socklen_t *fromlen); ssize_t 相當於 long int,socklen_t 相當於int ,這裏用這個名字為的是提高代碼的自説明性。
中文名
接收函數
外文名
recvfrom
函數原型:
ssize_t recvfrom
參    數
sockfd
返回值
recv,recvmsg

目錄

recvfrom參數

sockfd:標識一個已連接套接口的描述字。
buf:接收數據緩衝區
len:緩衝區長度。
flags:調用操作方式。是以下一個或者多個標誌的組合體,可通過“ | ”操作符連在一起:
MSG_DONTWAIT:操作不會被阻塞。
MSG_ERRQUEUE: 指示應該從套接字的錯誤隊列上接收錯誤值,依據不同的協議,錯誤值以某種輔佐性消息的方式傳遞進來,使用者應該提供足夠大的緩衝區。導致錯誤的原封包通過msg_iovec作為一般的數據來傳遞。導致錯誤的數據報原目標地址作為msg_name被提供。錯誤以sock_extended_err結構形態被使用,定義如下
#define SO_EE_ORIGIN_NONE 0
#define SO_EE_ORIGIN_LOCAL 1
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3
struct sock_extended_err
{
u_int32_t ee_errno;
u_int8_t ee_origin;
u_int8_t ee_type;
u_int8_t ee_code;
u_int8_t ee_pad;
u_int32_t ee_info;
u_int32_t ee_data;
};
MSG_PEEK:指示數據接收後,在接收隊列中保留原數據,不將其刪除,隨後的讀操作還可以接收相同的數據。
MSG_TRUNC:返回封包的實際長度,即使它比所提供的緩衝區更長, 只對packet套接字有效。
MSG_WAITALL:要求阻塞操作,直到請求得到完整的滿足。然而,如果捕捉到信號,錯誤或者連接斷開發生,或者下次被接收的數據類型不同,仍會返回少於請求量的數據。
MSG_EOR:指示記錄的結束,返回的數據完成一個記錄。
MSG_TRUNC:指明數據報尾部數據已被丟棄,因為它比所提供的緩衝區需要更多的空間。
MSG_CTRUNC:指明由於緩衝區空間不足,一些控制數據已被丟棄。
MSG_OOB:指示接收到out-of-band數據(即需要優先處理的數據)。
MSG_ERRQUEUE:指示除了來自套接字錯誤隊列的錯誤外,沒有接收到其它數據。
from:(可選)指針,指向裝有源地址的緩衝區。
fromlen:(可選)指針,指向from緩衝區長度值。

recvfrom返回值

如果正確接收返回接收到的字節數,失敗返回-1.
相關函數 recv,recvmsg,send,sendto,socket
函數説明:recvfrom()用來接收遠程主機經指定的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 傳給系統調用的參數不正確。

recvfrom範例

/*利用socket的UDPclient
此程序會連線UDPserver,並將鍵盤輸入的字符串傳給server。
UDPserver範例請參考sendto()。
*/
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.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,(struct sockaddr*)&addr,addr_len);
/*接收server端返回的字符串*/
len=recvfrom(s,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,(socklen_t*)
&addr_len);
printf(“receive:%s”,buffer);
}
}
執行(先執行udpserver再執行udpclient)
hello/*從鍵盤輸入字符串*/
receive:hello/*server端返回來的字符串*/