socketpair
- 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读;
- 如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功;
- 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副sv[0]和sv[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
const char* str = "SOCKET PAIR TEST.";
int main(int argc, char* argv[]){
int socket_pair[2]; //两个socket
pid_t id;
//创建socketpair,socketpair()函数用于创建一对无名的、相互连接的套接子。
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1){
printf("Error, socketpair create failed, errno(%d): %s
", errno, strerror(errno));
return 1;//EXIT_FAILURE;
}
//创建子进程
id =fork();
if(id == 0){
//子进程
char buffer[512]={0, };
//子进程关闭管道4,子进程关闭[1]socket
close(socket_pair[1]);
while(1){
//发送数据给父进程
printf("childer send
");
write(socket_pair[0], str , strlen(str));
sleep(1);
//接收父进程数据
ssize_t len = read(socket_pair[0], buffer, sizeof(buffer));
if(len > 0 ){
buffer[len] = ' ';
printf("childer: recv from parent : %s
",buffer);
}
}
}else if(id > 0){
//父进程
char buffer[512]={0, };
//父进程关闭管道3
close(socket_pair[0]); //父进程关闭0
while(1){
//接收子进程数据
ssize_t len = read(socket_pair[1], buffer, sizeof(buffer));
if(len > 0 ){
buffer[len] = ' ';
printf("father: recv from childer : %s
",buffer);
}
sleep(1);
//发送数据给父进程
printf("father send
");
write(socket_pair[1], str , strlen(str));
}
}else{
printf("Error, fork failed, errno(%d): %s
", errno, strerror(errno));
return 1;//EXIT_FAILURE;
}
return 0;
}
g++ hello.cpp -o hello
./hello