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]中讀取”
整個流程就是,子進程寫父進程讀和父進程寫子進程讀同時在進行:上一張圖看看:

截取一段代碼,兩個紅色線的方向,都是從一個進程的寫到另一個進程的讀,同時進行,看運行結果:

打印時,成對打印,雙向通信!
賜教!
