在这次的linux网络编程复习的阶段我完成了socketpair()函数创建套接字,完成一个进程A打开一个文件描述符,进程B创建socketpair()套接字,在B中唤起进程A并传递文件描述符。在B 中输出文件中的信息。重点代码如下,发送A中打开的文件描述符。
ssize_t send_fd(int fd, void *data, size_t bytes, int sendfd){//sendfd为文件描述符
struct msghdr msghdr_send;<这个结构体中struct msghdr{
void * name;
int namelen;
char *msg_control;
int msg_controllen;
void *msg_iov;
int msg_iovlen;
int flag;
}
其中msg_control指向一个附属空间,msg_controllen表示其长度。msg_iov指向一个struct iovec的结构
体数组,name指向路径。当使用readmsg时而接收方不是使用sendmsgflag将被置为1
struct iovec{
ptr_t iov_base;
size_t iov_len;
}
iov_base存放字符串,iov_len存放的是字符串长度。
>
struct iovec iov[1];
size_t n;
union{
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
}control_un;
struct cmsghdr*pcmsghdr = NULL; < struct cmsghdr结构体:
struct cmsghdr{
socklen_t cmsg_len;
int cmsg_level;
int cmsg_type;
u_char cmsg_data[];
}
其中cmsg_len表示附属数据的字节计数,包含结构体头的尺寸
这个值是由CMSG_LEN()宏计算。cmsg_level这个值是原始协议
cmsg_data这个并不是实际存在,他是用来指明实际额外附属数据的所在地
cmsg_level描述 SCM_RIGHTS所属数据对象是一个文件描述符
SCM_CREDENTIALS 附属数据对象是一个包含证书信息的结构
struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *msgh);
这个宏返回一个指向附属数据缓冲区内的第一个附属对象的struct cmsghdr指针。
输入值为是指向struct msghdr结构的指针
struct cmsghdr *CMSG_NXTHDR(struct msghdr*msgh, struct cmsghdr *cmsg);
这个用于返回下一个附属数据对象的struct cmsghdr指针,这个宏会接收俩个输入参数
指向struct msghdr的指针 指向当前struct cmsghdr的指针如果没有下一个附属数据对象
返回NULL
size_t CMSG_ALIGN(size_t length);
指定一个字节长度作为输入,这个宏会计算一个新的长度,这个新的长度包括为了
维护对齐所需的额外填充字节。
size_t CMSG_SPACE(size_t length);
这个宏是用来计算附属数据以及其头部所需要的总空白
size_t CMSG_LEN(size_t length);
这个宏是我们希望放在附属缓冲区中的对象的尺寸作为输入参数,
void *CMSG_DATA(struct cmsghdr *cmsg);
这个宏接收一个指向cmsghdr结构的指针,返回指针会跟随在头部及其填充字
节后的附属数据段
>
msghdr_send.msg_control = control_un.control;
msghdr_send.msg_controllen = sizeof(control_un.control);
pcmsghdr = CMSG_FIRSTHDR(&msghdr_send);
pcmsghdr->cmsg_len = CMSG_LEN(sizeof(int));
pcmsghdr->cmsg_level = SOL_SOCKET;
pcmsghdr->cmsg_type = SCM_RIGHTS;
*((int *)CMSG_DATA(pcmsghdr)) = sendfd;
msghdr_send.msg_name = NULL;
msghdr_send.msg_namelen = 0;
iov[0].iov_base = data;
iov[0].iov_len = bytes;
msghdr_send.msg_iov = iov;
msghdr_send.msg_iovlen = 1;
return (sendmsg(fd, &msghdr_send,0));
}
WIFEXITED(status)如果子进程正常结束则为非0值。
WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED 来判断是否正常结束才能使用此宏。
WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真
WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED 来判断后才使用此宏。
WIFSTOPPED(status)如果子进程处于暂停执行情况则此宏值为真。一般只有使用WUNTRACED 时才会有此情况。
WSTOPSIG(status)取得引发子进程暂停的信号代码,