轉載自:https://blog.csdn.net/xifens/article/details/53714814
socketpair()函數的聲明:
#include <sys/types.h>
#include <sys/socket.h>
int socketpair(int d, int type, int protocol, int sv[2]);
socketpair()函數用於創建一對無名的、相互連接的套接子。
如果函數成功,則返回0,創建好的套接字分別是sv[0]和sv[1];否則返回-1,錯誤碼保存於errno中。
基本用法:
1. 這對套接字可以用於全雙工通信,每一個套接字既可以讀也可以寫。例如,可以往sv[0]中寫,從sv[1]中讀;或者從sv[1]中寫,從sv[0]中讀;
2. 如果往一個套接字(如sv[0])中寫入後,再從該套接字讀時會阻塞,只能在另一個套接字中(sv[1])上讀成功;
3. 讀、寫操作可以位於同一個進程,也可以分別位於不同的進程,如父子進程。如果是父子進程時,一般會功能分離,一個進程用來讀,一個用來寫。因爲文件描述副sv[0]和sv[1]是進程共享的,所以讀的進程要關閉寫描述符, 反之,寫的進程關閉讀描述符。
舉例:
一、讀寫操作位於同一進程
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <error.h>
#include <errno.h>
#include <sys/socket.h>
#include <stdlib.h>
const char* str = "SOCKET PAIR TEST.";
int main(int argc, char* argv[]){
char buf[128] = {0};
int socket_pair[2];
pid_t pid;
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1 ) {
printf("Error, socketpair create failed, errno(%d): %s\n", errno, strerror(errno));
return EXIT_FAILURE;
}
int size = write(socket_pair[0], str, strlen(str));
//可以讀取成功;
read(socket_pair[1], buf, size);
printf("Read result: %s\n",buf);
return EXIT_SUCCESS;
}
二、讀寫操作位於不同進程
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <error.h>
#include <errno.h>
#include <sys/socket.h>
#include <stdlib.h>
const char* str = "SOCKET PAIR TEST.";
int main(int argc, char* argv[]){
char buf[128] = {0};
int socket_pair[2];
pid_t pid;
if(socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1 ) {
printf("Error, socketpair create failed, errno(%d): %s\n", errno, strerror(errno));
return EXIT_FAILURE;
}
pid = fork();
if(pid < 0) {
printf("Error, fork failed, errno(%d): %s\n", errno, strerror(errno));
return EXIT_FAILURE;
} else if(pid > 0) {
//關閉另外一個套接字
close(socket_pair[1]);
int size = write(socket_pair[0], str, strlen(str));
printf("Write success, pid: %d\n", getpid());
} else if(pid == 0) {
//關閉另外一個套接字
close(socket_pair[0]);
read(socket_pair[1], buf, sizeof(buf));
printf("Read result: %s, pid: %d\n",buf, getpid());
}
for(;;) {
sleep(1);
}
return EXIT_SUCCESS;
}