一、双向通信(socketpair)
socketpair()函数用于创建一对无名的、相互连接的套接子,如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1];否则返回-1,错误码保存于errno中。
- socketpair()函数的声明:
#include <sys/types.h> #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int sv[2]);
- 参数说明:
参数1(domain):表示协议族,在Linux下只能为AF_LOCAL或者AF_UNIX。(自从Linux 2.6.27后也支持SOCK_NONBLOCK和SOCK_CLOEXEC)
参数2(type):表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。SOCK_STREAM是基于TCP的,而SOCK_DGRAM是基于UDP的
参数3(protocol):表示类型,只能为0
参数4(sv[2]):套节字柄对,该两个句柄作用相同,均能进行读写双向操作
返回errno含义:
EAFNOSUPPORT:本机上不支持指定的address。
EFAULT: 地址sv无法指向有效的进程地址空间内。
EMFILE: 已经达到了系统限制文件描述符,或者该进程使用过量的描述符。
EOPNOTSUPP:指定的协议不支持创建套接字对。
EPROTONOSUPPORT:本机不支持指定的协议。
- 注意:
1.该函数只能用于UNIX域(LINUX)下。
2.只能用于有亲缘关系的进程(或线程)间通信。
3.所创建的套节字对作用是一样的,均能够可读可写(而管道PIPE只能进行单向读或写)。
4.这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读;
5.该函数是阻塞的,且如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功;
6. 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副sv[0]和sv[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。
示例代码1(同一进程不同线程间通信):
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#define SOCKET_BUFFER_SIZE (32768U)
/* 参考:
* frameworks
ativelibsinputInputTransport.cpp
*/
void *function_thread1 (void *arg)
{
int fd = (int)arg;
char buf[500];
int len;
int cnt = 0;
while (1)
{
/* 向 main线程发出: Hello, main thread */
len = sprintf(buf, "Hello, main thread, cnt = %d", cnt++);
write(fd, buf, len);
/* 读取数据(main线程发回的数据) */
len = read(fd, buf, 500);
buf[len] = '