目录
1.系统调用流程
2.接收函数系列
2.1 recv函数
2.2 recvfrom函数
2.3 recvmsg函数
2.4 read函数
2.5 readv函数
1.系统调用流程
图 1
2.接收函数系列
2.1 recv函数
套接字接收函数。
-
#include <sys/types.h> -
#include <sys/socket.h> -
ssize_t recv(int sockfd, void *buf, size_t len, int flags); -
参数: -
sockfd:套接字文件描述符 -
buf:接收缓冲区 -
len:接收数据长度 -
flags:标识 -
返回值: -
成功:返回接收的字节数 -
失败:返回-1,并设置errno
2.2 recvfrom函数
套接字接收函数,能够获取对端套接字地址信息。
-
#include <sys/types.h> -
#include <sys/socket.h> -
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 <sys/types.h> -
#include <sys/socket.h> -
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); -
参数: -
sockfd:套接字文件描述符 -
msg:接收消息体 -
flags:标识 -
返回值: -
成功:返回接收的字节数 -
失败:返回-1,并设置errno

图 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所示。

图 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 <unistd.h> -
ssize_t read(int fd, void *buf, size_t count); -
参数: -
fd:套接字文件描述符 -
buf:接收缓冲区 -
count:接收数据长度 -
返回值: -
成功:返回接收的字节数 -
失败:返回-1,并设置errno
2.5 readv函数
文件描述符接收函数,可用于套接字批量接收操作接收。
-
#include <sys/uio.h> -
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);
1544

被折叠的 条评论
为什么被折叠?



