標籤:
1.socketpair
2.sendmsg/recvmsg
3.UNIX域通訊端傳遞描述字
功能:建立一個圈雙工的流管道
原型:
int socketpair(int domain, int type, int protocol, int sv[2]);
參數 domain :協議家族
type: 通訊端種類
protocol:協議種類
sv:返回的通訊端對
傳回值: 成功返回0, 失敗返回-1
通過sockpair建立的全雙通管道可以實現父子間進程通訊
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)int main(int argc, const char *argv[]){ int sockfds[2]; int ret = socket(PF_UNIX, SOCK_STREAM, 0, sockfds); if(ret == -1) ERR_EXIT("sockpair"); pid_t pid; pid = fork(); if(pid == -1) ERR_EXIT("fork"); if(pid > 0) { int val = 0; close(sockfd[1]); while(1) { ++val; printf("sending data: %d\n", val); write(sockfds[0], &val, sizeof(val)); read(sockfd[0], &val, sizeof(val)); printf("data received: %d\n", val); sleep(1); } }else if(pid == 0) { int val; close(sockfds[0]); while(1) { read(sockfds[1], &val, sizeof(val)); ++val; write(sockfds[1], &val, sizeof(val)); } } return 0; }
會發現val的值不停的增加,並且在父子間進程被傳遞;
下面我們來看一下更加強大的sendmsg函數
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
struct 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 */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
參數解釋:
1.void *msg_name; /* optional address */
socklen_t msg_namelen;
這兩個參數確定發送的地址
2。struct iovec *msg_iov; /* scatter/gather array */
我們要發送的資料存放在這個結構體中
struct iovec {
void *iov_base; /* Starting address */ 這個相當於緩衝區
size_t iov_len; /* Number of bytes to transfer */ 緩衝區長度
};
結構如上
++++++
這是一個msghdr的
3.再下面幾個資料時輔助資訊。
我們通過自己封裝sendmsg實現傳遞描述符
自己寫一個send
linux:利用socketpair來在進程間傳遞描述符