recvfrom(数学定义)

2023-05-08 52阅读

温馨提示:这篇文章已超过429天没有更新,请注意相关的内容是否还可用!

recvfrom

数学定义

recvfrom函数(经socket接收数据):函数原型:ssize_trecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,socket_t*fromlen),ssize_t相当于int,socket_t相当于int,这里用这个名字为的是提高代码的自说明性。函数说明:recvfrom()用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度,参数flags一般设0,其他数值定义参考recv(),参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数,参数fromlen为sockaddr的结构长度,

中文名 接收函数
外文名 recvfrom
函数原型 ssize_t recvfrom
参数 sockfd
返回值 recv,recvmsg

参数

sockfd:标识一个已连接套接口的描述字。

buf:接收数据缓冲区。

len:缓冲区长度。

flags:调用操作方式。是以下一个或者多个标志的组合体,可通过or操作连在一起:

MSG_DONTWAIT:操作不会被阻塞。

MSG_ERRQUEUE:指示应该从套接字的错误队列上接收错误值,依据不同的协议,错误值以某种辅佐性消息的方式传递进来,使用者应该提供足够大的缓冲区。导致错误的原封包通过msg_iovec作为一般的数据来传递。导致错误的数据报原目标地址作为msg_name被提供。错误以sock_extended_err结构形态被使用,定义如下

#defineSO_EE_ORIGIN_NONE0

#defineSO_EE_ORIGIN_LOCAL1

#defineSO_EE_ORIGIN_ICMP2

#defineSO_EE_ORIGIN_ICMP63

structsock_extended_err

{

u_int32_tee_errno,

u_int8_tee_origin,

u_int8_tee_type,

u_int8_tee_code,

u_int8_tee_pad,

u_int32_tee_info,

u_int32_tee_data,},

MSG_PEEK:指示数据接收后,在接收队列中保留原数据,不将其删除,随后的读操作还可以接收相同的数据。

MSG_TRUNC:返回封包的实际长度,即使它比所提供的缓冲区更长,只对packet套接字有效。

MSG_WAITALL:要求阻塞操作,直到请求得到完整的满足。然而,如果捕捉到信号,错误或者连接断开发生,或者下次被接收的数据类型不同,仍会返回少于请求量的数据。

MSG_EOR:指示记录的结束,返回的数据完成一个记录。

MSG_TRUNC:指明数据报尾部数据已被丢弃,因为它比所提供的缓冲区需要更多的空间。

MSG_CTRUNC:指明由于缓冲区空间不足,一些控制数据已被丢弃。

MSG_OOB:指示接收到out-of-band数据(即需要优先处理的数据)。

MSG_ERRQUEUE:指示除了来自套接字错误队列的错误外,没有接收到其它数据。

from:(可选)指针,指向装有源地址的缓冲区。

fromlen:(可选)指针,指向from缓冲区长度值。

返回值

如果正确接收返回接收到的字节数,失败返回-1,

相关函数recv,recvmsg,send,sendto,socket

函数说明:recvfrom()用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度,参数flags一般设0,其他数值定义参考recv(),参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数,参数fromlen为sockaddr的结构长度,相关函数:recv, recvmsg, send, sendto, socket

返回值:成功则返回接收到的字符数,失败返回-1,

错误代码

EBADF参数s非合法的socket处理代码

EFAULT参数中有一指针指向无法存取的内存空间。

ENOTSOCK参数s为一文件描述词,非socket。

EINTR被信号所中断。

EAGAIN此动作会令进程阻断,但参数s的socket为不可阻断。

ENOBUFS系统的缓冲内存不足

ENOMEM核心内存不足

EINVAL传给系统调用的参数不正确。

范例

,*利用socket的UDPclient

此程序会连线UDPserver,并将键盘输入的字符串传给server。

UDPserver范例请参考sendto

#include

#include

#include

#include

#include

#include

#include

#definePORT2345

#defineSERVER_IP“127,0,0,1”

main()

ints,len,

structsockaddr_inaddr,

intaddr_len=sizeof(structsockaddr_in),

charbuffer,

,*建立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,(structsockaddr*)&addr,addr_len),

,*接收server端返回的字符串*,

len=recvfrom(s,buffer,sizeof(buffer),0,(structsockaddr*)&addr,&addr_len),

printf(“receive:%s”,buffer),

执行(先执行udpserver再执行udpclient)

hello,*从键盘输入字符串*,

receive:hello,*server端返回来的字符串*,

参考资料

--1--

目录[+]