SOcketpairに関する実験(linuxベース)
3955 ワード
実験結果:
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の古いデータが失われることはなく、新しい書き込みデータが古いデータを上書きすることを示すだけである.
コード:
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);
}