recv作用c语言,C语言 recv/recvfrom/recvmsg系统调用

recv/recvfrom/recvmsg系统调用

功能描述:

从套接字上接收一个消息。对于recvfrom 和 recvmsg,可同时应用于面向连接的和无连接的套接字。recv一般只用在面向连接的套接字,几乎等同于recvfrom,只要将recvfrom的第五个参数设置NULL。

如果消息太大,无法完整存放在所提供的缓冲区,根据不同的套接字,多余的字节会丢弃。

假如套接字上没有消息可以读取,除了套接字已被设置为非阻塞模式,否则接收调用会等待消息的到来。

用法:

1

2

3

4

5

6#include

#include

ssize_t recv(int sock, void *buf, size_t len, int flags);

ssize_t recvfrom(int sock, void *buf, size_t len, int flags,

struct sockaddr *from, socklen_t *fromlen);

ssize_t recvmsg(int sock, struct msghdr *msg, int flags);

参数:

sock:索引将要从其接收数据的套接字。

buf:存放消息接收后的缓冲区。

len:buf所指缓冲区的容量。

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

MSG_DONTWAIT:操作不会被阻塞。

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#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; /* error number */

u_int8_t ee_origin; /* where the error originated */

u_int8_t ee_type; /* type */

u_int8_t ee_code; /* code */

u_int8_t ee_pad;

u_int32_t ee_info; /* additional information */

u_int32_t ee_data; /* other data */

/* More data may follow */

};

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

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

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

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

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

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

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

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

from:指向存放对端地址的区域,如果为NULL,不储存对端地址。

fromlen:作为入口参数,指向存放表示from最大容量的内存单元。作为出口参数,指向存放表示from实际长度的内存单元。

msg:指向存放进入消息头的内存缓冲,结构形态如下

1

2

3

4

5

6

7

8

9struct msghdr {

void *msg_name; /* optional address */

socklen_t msg_namelen; /* size of address */

struct iovec *msg_iov; /* scatter/gather array */

size_t msg_iovlen; /* # elements in msg_iov */

void *msg_control; /* ancillary data, see below */

socklen_t msg_controllen; /* ancillary data buffer len */

int msg_flags; /* flags on received message */

};

可能用到的数据结构有

1

2

3

4

5

6

7struct cmsghdr {

socklen_t cmsg_len; /* data byte count, including hdr */

int cmsg_level; /* originating protocol */

int cmsg_type; /* protocol-specific type */

/* followed by

u_char cmsg_data[]; */

};

返回说明:

成功执行时,返回接收到的字节数。另一端已关闭则返回0。失败返回-1,errno被设为以下的某个值

EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时

EBADF:sock不是有效的描述词

ECONNREFUSE:远程主机阻绝网络连接

EFAULT:内存空间访问出错

EINTR:操作被信号中断

EINVAL:参数无效

ENOMEM:内存不足

ENOTCONN:与面向连接关联的套接字尚未被连接上

ENOTSOCK:sock索引的不是套接字

回答: 在C语言中,使用socket函数可以创建一个套接字描述符。例如,使用g++编译器可以使用以下命令编译一个名为socketTest的程序: g++ -pthread socket.c -o socketTest。\[1\]在使用套接字时,可以使用bind函数将套接字与本地IP地址绑定。bind函数的参数包括套接字描述符、指向本地IP地址的结构体指针和结构长度。\[2\]另外,C语言中还提供了一些用于读写套接字的函数,如read、write、send、recv、sendto、recvfrom、sendmsgrecvmsg。其中,recvmsg和sendmsg函数是最通用的I/O函数,可以替换其他函数。\[3\]这些函数的具体用法可以参考相关的C语言文档和教程。 #### 引用[.reference_title] - *1* *3* [【socket】C语言的Socket网络编程](https://blog.csdn.net/bandaoyu/article/details/83312254)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言——socket通信详解](https://blog.csdn.net/WU2629409421perfect/article/details/114448461)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值