socket recv函数系列,recv,recvfrom,recvmsg,一文彻底弄懂,可作参考手册

目录

1.系统调用流程

2.接收函数系列

2.1 recv函数

2.2 recvfrom函数

2.3 recvmsg函数

2.4 read函数

2.5 readv函数


1.系统调用流程

socket recv函数系列,recv,recvfrom,recvmsg,一文彻底弄懂,可作参考手册_第1张图片图 1

 

2.接收函数系列

2.1 recv函数

套接字接收函数。

#include   
#include 

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

参数:
sockfd:套接字文件描述符
buf:接收缓冲区
len:接收数据长度
flags:标识

返回值:
成功:返回接收的字节数
失败:返回-1,并设置errno


2.2 recvfrom函数

套接字接收函数,能够获取对端套接字地址信息。

#include   
#include 

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,            
struct sockaddr *src_addr, socklen_t *addrlen);

参数:
sockfd:套接字文件描述符
buf:接收缓冲区
len:接收数据长度
flags:标识
src_addr:对端套接字地址
addrlen:对端套接字地址长度

返回值:
成功:返回接收的字节数
失败:返回-1,并设置errno


2.3 recvmsg函数

套接字批量接收函数。

#include   
#include 

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

参数:
sockfd:套接字文件描述符
msg:接收消息体
flags:标识

返回值:
成功:返回接收的字节数
失败:返回-1,并设置errno

socket recv函数系列,recv,recvfrom,recvmsg,一文彻底弄懂,可作参考手册_第2张图片

图 2 struct msghdr结构体解析

 
recvmsg接收原理:

  • void *msg_name保存对端套接字地址,socklen_t msg_namelen为套接字地址长度。
  • struct iovec *msg_iov为接收单元结构体指针,指向一块连续的struct iovec区域,每一个区域为一个接收缓冲区,可以通过size_t msg_iovlen指定一次接收的单元数量,从而完成批量接收操作。
  • struct iovec为接收单元,void *iov_base指向一块内存缓冲区,unsigned int iov_len为缓冲区长度,接收数据会先填满一个内存缓冲区才会继续填写下一个缓冲区,如图3所示。

socket recv函数系列,recv,recvfrom,recvmsg,一文彻底弄懂,可作参考手册_第3张图片

图 3

 
使用示例:

#define PACK_NUM (50)
#define MAX_BUF_LEN (1500)

struct sockaddr_in peer = {0};
socklen_t addrlen = sizeof(peer);

char *buf_arr = (char *)malloc(PACK_NUM * MAX_BUF_LEN);
struct iovec *iov = (struct iovec *)malloc(PACK_NUM * sizeof(struct iovec));

for (int i = 0; i < PACK_NUM; i++) {
    iov[i].iov_base = &buf_arr[i * MAX_BUF_LEN];
    memset(iov[i].iov_base, 0, MAX_BUF_LEN);
    iov[i].iov_len = strlen(REQUEST_STR1);
}

struct msghdr msg = {0};
msg.msg_name = &peer;
msg.msg_namelen = sizeof(peer);
msg.msg_iov = iov;
msg.msg_iovlen = 10;

ssize_t len = recvmsg(sockfd, &msg, 0);


2.4 read函数

文件描述符接收函数,可用于套接字接收。

#include 

ssize_t read(int fd, void *buf, size_t count);

参数:
fd:套接字文件描述符
buf:接收缓冲区
count:接收数据长度

返回值:
成功:返回接收的字节数
失败:返回-1,并设置errno


2.5 readv函数

文件描述符接收函数,可用于套接字批量接收操作接收。

#include 

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

参数:
fd:套接字文件描述符
iov:接收单元结构体指针
iovcnt:接收单元数量

返回值:
成功:返回接收的字节数
失败:返回-1,并设置errno


readv接收原理:

  • struct iovec为接收单元,void *iov_base指向一块内存缓冲区,unsigned int iov_len为缓冲区长度。
  • int iovcnt为接收单元数量。
  • readv函数和recvmsg函数接收过程类似。


使用示例:

#define PACK_NUM (50)
#define MAX_BUF_LEN (1500)

char *buf_arr = (char *)malloc(PACK_NUM * MAX_BUF_LEN);
struct iovec *iov = (struct iovec *)malloc(PACK_NUM * sizeof(struct iovec));

for (int i = 0; i < PACK_NUM; i++) {
    iov[i].iov_base = &buf_arr[i * MAX_BUF_LEN];
    memset(iov[i].iov_base, 0, MAX_BUF_LEN);
    iov[i].iov_len = strlen(REQUEST_STR1);
}

readv(sockfd, iov, 10);

你可能感兴趣的:(Linux网络编程,linux,tcp/ip,物联网,网络,c语言)