关于socketpair 的实验(基于linux)

实验结果:

向s0写入数据,则可从s1读到数据,反之亦然。
如果没有向s0写入数据,则读取s1的动作会阻塞住,直到s0被写入数据。
在进程A中向s0写入数据后,也可在进程A中从s1把该数据读出来,当然也可以在进程B中从s1把该数据读出来。作为进程间通信的方法,通常的用法都是后者。
这样看来,通讯似乎是单向的,其实socketpair的全双工用法也很简单:
让进程A使用s0,则进程A可向s0写入,也可从s0读取。让进程B使用s1,则进程B可向s1写入,也可从s1读取。
如此,
进程A向s0写入的内容,便可由进程B从s1读取出来。
进程B向s1写入的内容,便可由进程A从s0读取出来。
即实现了AB两个进程间的全双工通讯。

向s0写入数据的过程中,如果未从s1读取,则s0的写指针会随着每次写入动作后移,这样保证了新写入的数据不会覆盖旧数据。一旦从s1读取数据的动作发生,则s0的写指针立刻回到起始位置!也就是说每次对s1的读取动作都会导致s0的写指针复位。但是注意,写指针复位并不会导致s0的旧数据丢失,只表示新的写入数据会覆盖旧数据。


代码:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utils/Log.h>
#include <cutils/sockets.h>
#include <time.h>
#include <cutils/properties.h>

#define BUF_SIZE 30

int main(void)
{
	int socket_pair[2];
	char * string_1 = "abcdefghijk";
	char * string_2 = "ABCDEFGHIJK";
	char * buf = (char*)calloc(1 , BUF_SIZE);//need to check memory allocation errors!
	pid_t ret_val;
	pid_t pid_parent = -1;
	pid_t pid_child = -1;

/*============	socketpair init ============*/

	if(-1 == socketpair(AF_UNIX,SOCK_STREAM,0,socket_pair)) {
		printf("create unnamed socket pair failed:%s\n",strerror(errno));
		exit(-1);
	}

/*============	fork a new process ============*/

	ret_val = fork();
	if(ret_val < 0) {
		printf("Fork failed:%s\n", strerror(errno));
		exit(-1);
	}

	if(ret_val > 0) {
		pid_parent = getpid();
		printf("this is the PARENT process (pid=%4d)\n", pid_parent);
	}
	else {
		pid_child = getpid();
		printf("this is the CHILD process (pid=%4d)\n", pid_child);
		//close(s[0]);
	}

/*============  the work of each process ============*/

	if(pid_parent == getpid()) {// the parent process
		int i = 0;
		char* p = NULL;
		p = string_1;

		close(socket_pair[1]);

		while(i<10) {

			printf("				PARENT: sleep...\n");
			sleep(2);
			printf("				PARENT: awake...\n");

			printf("				PARENT: writing...\n");
			if((write(socket_pair[0] , p , 1)) == -1 ) {
				printf("				PARENT: write to socket_pair[0] ERROR: %s\n", strerror(errno));
				exit(-1);
			}
			else {
				printf("				PARENT: write to socket_pair[0]: %c\n", *p);
			}

			printf("				PARENT: reading...\n");
			if((read(socket_pair[0] , buf , BUF_SIZE)) == -1 ) {
				printf("				PARENT: read from socket_pair[0] ERROR: %s\n", strerror(errno));
				exit(-1);
			}
			else {
				printf("				PARENT: read from socket_pair[0]: %s\n", buf);
			}

			i++;
			p++;
		}
		printf("				PARENT: exit\n");
	}
	else if(pid_child == getpid()) {// the child process
		int i = 0;
		char* p = NULL;
		p = string_2;

		close(socket_pair[0]);

		while(i<10) {
			printf("CHILD: reading...\n");
			if((read(socket_pair[1] , buf , BUF_SIZE)) == -1 ) {
				printf("CHILD: read from socket_pair[1] ERROR: %s\n", strerror(errno));
				exit(-1);
			}
			else {
				printf("CHILD: read from socket_pair[1]: %s\n", buf);
			}

			printf("CHILD: writing...\n");
			if((write(socket_pair[1] , p , 1)) == -1 ) {
				printf("CHILD: write to socket_pair[1] ERROR: %s\n", strerror(errno));
				exit(-1);
			}
			else {
				printf("CHILD: write to socket_pair[1]: %c\n", *p);
			}

			printf("CHILD: sleep...\n");
			sleep(2);
			printf("CHILD: awake...\n");

			i++;
			p++;
		}
		
		printf("CHILD: exit\n");
	}

	exit(0);
}





你可能感兴趣的:(linux,socket,进程通讯,socketpair)