Linux下socketpair介紹:
socketpair創建了一對無名的套接字描述符(只能在AF_UNIX域中使用),描述符存儲於一個二元數組,例如sv[2] .這對套接字可以進行雙工通信,每一個描述符既可以讀也可以寫。這個在同一個進程中也可以進行通信,向sv[0]中寫入,就可以從sv[1]中讀取(只能從sv[1]中讀取),也可以在sv[1]中寫入,然后從sv[0]中讀取;但是,若沒有在0端寫入,而從1端讀取,則1端的讀取操作會阻塞,即使在1端寫入,也不能從1讀取,仍然阻塞;
Linux實現了一個源自BSD的socketpair調用,可以實現在同一個文件描述符中進行讀寫的功能。該系統調用能創建一對已連接的UNIX族socket。在Linux中,完全可以把這一對socket當成pipe返回的文件描述符一樣使用,唯一的區別就是這一對文件描述符中的任何一個都可讀和可寫,函數原型如下:
<span style="font-size:18px;">int socketpair(int d, int type, int protocol, int sv[2]);</span>
參數介紹:
socketpair()函數建立一對匿名的已經連接的套接字,其特性由協議族d、類型type、協議protocol決定,建立的兩個套接字描述符會放在sv[0]和sv[1]中。
第1個參數d,表示協議族,只能為AF_LOCAL或者AF_UNIX;
第2個參數type,表示類型,只能為0。
第3個參數protocol,表示協議,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字對是管道流,與一般的管道相區別的是,套接字對建立的通道是雙向的,即每一端都可以進行讀寫。參數sv,用於保存建立的套接字對。
socketpair()函數建立一對匿名的已經連接的套接字,其特性由協議族d、類型type、協議protocol決定,建立的兩個套接字描述符會放在sv[0]和sv[1]中。
第1個參數d,表示協議族,只能為AF_LOCAL或者AF_UNIX;
第2個參數type,表示類型,只能為0。
第3個參數protocol,表示協議,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字對是管道流,與一般的管道相區別的是,套接字對建立的通道是雙向的,即每一端都可以進行讀寫。參數sv,用於保存建立的套接字對。
看源碼:
/* *進程雙向通信 */ #include<stdio.h> #include<string.h> #include<sys/types.h> #include<stdlib.h> #include<unistd.h> #include<sys/socket.h> int main() { int sv[2]; //一對無名的套接字描述符 if(socketpair(PF_LOCAL,SOCK_STREAM,0,sv) < 0) //成功返回零 失敗返回-1 { perror("socketpair"); return 0; } pid_t id = fork(); //fork出子進程 if(id == 0) //孩子 { //close(sv[0]); //在子進程中關閉讀 close(sv[1]); //在子進程中關閉讀 const char* msg = "我是孩子\n"; char buf[1024]; while(1) { // write(sv[1],msg,strlen(msg)); write(sv[0],msg,strlen(msg)); sleep(1); //ssize_t _s = read(sv[1],buf,sizeof(buf)-1); ssize_t _s = read(sv[0],buf,sizeof(buf)-1); if(_s > 0) { buf[_s] = '\0'; printf("孩子說 : %s\n",buf); } } } else //父親 { //close(sv[1]);//關閉寫端口 close(sv[0]);//關閉寫端口 const char* msg = "我是父親\n"; char buf[1024]; while(1) { //ssize_t _s = read(sv[0],buf,sizeof(buf)-1); ssize_t _s = read(sv[1],buf,sizeof(buf)-1); if(_s > 0) { buf[_s] = '\0'; printf("父親說 : %s\n",buf); sleep(1); } // write(sv[0],msg,strlen(msg)); write(sv[1],msg,strlen(msg)); } } return 0; }
這里只是代碼,整體流程,意思就是,父子進程間正在全雙工通信,個人理解即就是同時通信。
代碼中有兩行一樣,一行被注釋掉了,這正是說明博文第一段中的話:
“向sv[0]中寫入,就可以從sv[1]中讀取(只能從sv[1]中讀取),也可以在sv[1]中寫入,然后從sv[0]中讀取”
整個流程就是,子進程寫父進程讀和父進程寫子進程讀同時在進行:上一張圖看看:
截取一段代碼,兩個紅色線的方向,都是從一個進程的寫到另一個進程的讀,同時進行,看運行結果:
打印時,成對打印,雙向通信!
賜教!