这几天学习网络编程,踩了好多坑,网上这部分资料不多,例子也是抄来抄去。
sendmsg和recvmsg这两个接口是高级套接口,这两个接口支持一般数据的发送和接收,还支持多缓冲区的报文发送和接收(readv和sendv支持多缓冲区发送和接收),还可以在报文中带辅助数据。
还是先上代码
server 端
#include <iostream>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define DEFAULT_PORT 8080
#define MAXLINE 4096
#define MAX_NAME_LEN 4095
#define MAX_MMSG_NUM 10
int receive_message(int socket_fd, int* socket_num, int* sockets) {
struct iovec iov[1];
int32_t utm[MAX_MMSG_NUM];
char buf[CMSG_SPACE(sizeof(int) * MAX_MMSG_NUM)];
struct msghdr msg;
{
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_flags = 0;
msg.msg_iov = iov;
//msg.msg_iov = 0;
msg.msg_iovlen = sizeof(iov) /sizeof(iov[0]);
//msg.msg_iovlen = 0;
msg.msg_control = buf;
//msg.msg_control = NULL;
msg.msg_controllen = sizeof(buf);
//msg.msg_controllen = 0;
msg.msg_iov[0].iov_base = utm;
msg.msg_iov[0].iov_len = sizeof(utm);
}
errno = 0;
const int n = recvmsg(socket_fd, &msg, MSG_WAITALL);
std::cout << "receive finish n=" << n << "sizeof(utm)=" << sizeof(utm) << std::endl;
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
{
if (n <= 0) {
std::cout << "receive message faild, return " << strerror(errno) << std::endl;
return errno;
}
if(0 != (msg.msg_flags & (MSG_TRUNC | MSG_CONFIRM))) {
std::cout << "receive message truncated, flags=" << msg.msg_flags << std::endl;
return errno;
}
}
*socket_num = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int32_t);
int32_t* fd_arr = reinterpret_cast<int32_t*>(CMSG_DATA(cmsg));
for (int32_t i = 0; i < *sock