linux 管道通信socket 全双工示例

socketpair

  1. 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读;
  2. 如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功;
  3. 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副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\n", 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 \n");
			write(socket_pair[0], str , strlen(str));
			sleep(1);			
			//接收父进程数据
			ssize_t len = read(socket_pair[0], buffer, sizeof(buffer));
			if(len > 0 ){
				buffer[len] = '\0';
				printf("childer: recv from parent : %s \n",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] = '\0';
				printf("father: recv from childer : %s \n",buffer);				
			}
			sleep(1);
			//发送数据给父进程
			printf("father send \n");
			write(socket_pair[1], str , strlen(str));
		}		
	}else{		
		printf("Error, fork failed, errno(%d): %s\n", errno, strerror(errno));
        return 1;//EXIT_FAILURE;
	}	
	return 0;	
}
g++ hello.cpp -o hello 
./hello        

posted on 2020-09-09 14:46  WillingCPP  阅读(780)  评论(0编辑  收藏  举报

导航