SOcketpairに関する実験(linuxベース)


実験結果:
s 0にデータを書き込むと、s 1からデータを読み取ることができ、逆も同様である.
s 0にデータが書き込まれていない場合、s 1を読み出す動作は、s 0がデータに書き込まれるまでブロックされる.
プロセスAにおいてs 0にデータを書き込むと、プロセスAにおいてs 1からそのデータを読み出すようにしてもよいし、もちろんプロセスBにおいてs 1からそのデータを読み出すようにしてもよい.プロセス間通信の方法としては,通常の用法は後者である.
このように見ると、通信は一方向のようですが、socketpairの全二重の使い方も簡単です.
プロセスAにs 0を使用させると、プロセスAはs 0に書き込むことも、s 0から読み出すこともできる.プロセスBにs 1を使用させると、プロセスBはs 1に書き込むことも、s 1から読み出すこともできる.
このように、
プロセスAがs 0に書き込む内容は、プロセスBがs 1から読み出すことができる.
プロセスBがs 1に書き込む内容は、プロセスAによってs 0から読み出すことができる.
すなわち,AB 2プロセス間の全二重通信を実現した.
s 0にデータを書き込む過程で、s 1から読み取らなければ、s 0の書き込みポインタは書き込み動作のたびに後退し、新しく書き込まれたデータが古いデータを上書きしないことを保証する.s 1からデータを読み出す動作が発生すると、s 0の書き込みポインタはすぐに開始位置に戻る!すなわち、s 1の読み出し動作のたびに、s 0の書き込みポインタがリセットされる.ただし、書き込みポインタのリセットによりs 0の古いデータが失われることはなく、新しい書き込みデータが古いデータを上書きすることを示すだけである.
コード:
#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
",strerror(errno)); exit(-1); } /*============ fork a new process ============*/ ret_val = fork(); if(ret_val < 0) { printf("Fork failed:%s
", strerror(errno)); exit(-1); } if(ret_val > 0) { pid_parent = getpid(); printf("this is the PARENT process (pid=%4d)
", pid_parent); } else { pid_child = getpid(); printf("this is the CHILD process (pid=%4d)
", 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...
"); sleep(2); printf(" PARENT: awake...
"); printf(" PARENT: writing...
"); if((write(socket_pair[0] , p , 1)) == -1 ) { printf(" PARENT: write to socket_pair[0] ERROR: %s
", strerror(errno)); exit(-1); } else { printf(" PARENT: write to socket_pair[0]: %c
", *p); } printf(" PARENT: reading...
"); if((read(socket_pair[0] , buf , BUF_SIZE)) == -1 ) { printf(" PARENT: read from socket_pair[0] ERROR: %s
", strerror(errno)); exit(-1); } else { printf(" PARENT: read from socket_pair[0]: %s
", buf); } i++; p++; } printf(" PARENT: exit
"); } 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...
"); if((read(socket_pair[1] , buf , BUF_SIZE)) == -1 ) { printf("CHILD: read from socket_pair[1] ERROR: %s
", strerror(errno)); exit(-1); } else { printf("CHILD: read from socket_pair[1]: %s
", buf); } printf("CHILD: writing...
"); if((write(socket_pair[1] , p , 1)) == -1 ) { printf("CHILD: write to socket_pair[1] ERROR: %s
", strerror(errno)); exit(-1); } else { printf("CHILD: write to socket_pair[1]: %c
", *p); } printf("CHILD: sleep...
"); sleep(2); printf("CHILD: awake...
"); i++; p++; } printf("CHILD: exit
"); } exit(0); }