linux编程基础:使用socketpair实现双向通讯

socketpair是linux提供的一种双向通讯机制,它通过socket实现双向通讯。socketpair本身虽然实现了双向通讯的功能,但是也存在一些限制:比如只能在一个进程的线程之间进行双向通讯或者是在具有亲缘关系的进程间进行通讯。所以socketpair很少情况下会单独使用,它往往需要和其他编程机制结合起来使用才能发挥它真正的作用。本文举两个小例子来说明一下socketpair的基本用法。

一、在一个进程的线程间实现双向通讯

这个例子实现的功能是:编写一个具有两个线程的应用程序,让主线程和子线程通过socketpair进行双向通讯。完整的代码实现如下:

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

/* 定义socketpair缓冲区的大小 */
#define SOCKET_BUFFER_SIZE 		((32) * (1024))

#define BUFFER_SIZE		(256)	// 定义一个缓冲区的大小

/*
 *	定义子线程的主体函数
 */
static void *thread_run_func (void *arg)
{
	int thread_fd = (int)arg;
	char thread_buf[BUFFER_SIZE] = {0};
	int readlen;

	/* a、向主进程发送一个消息 */
	printf("(1) send to main thread : %s\n", "Hello,world!");
	write(thread_fd, "Hello,world!", sizeof("Hello,world!"));

	/* d、接收主进程发送的消息 */
	readlen = read(thread_fd, thread_buf, BUFFER_SIZE);
	thread_buf[readlen] = '\0';
	printf("(4) recv from main thread : %s\n", thread_buf);
}


/*	
 *	定义一个子线程,实现两个进程间的双向通讯
 */
int main(int argc, char *argv[])
{
	int sockets[2];
	int result;
	int bufferSize;

	pthread_t thread;

	char main_buf[BUFFER_SIZE]= {0};
	int readlen;

	/* 创建一个socketpair双向通讯的实例 */
	result = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
	if(-1 == result)
	{
		printf("socketpair error!\n");
		return -1;
	}

	/* 设置socketpair双向通讯各个缓冲区 */
	bufferSize = SOCKET_BUFFER_SIZE;
	setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));

	/* 创建一个子线程用于和主线程之间进行双向通讯 */
	result = pthread_create(&thread, NULL, thread_run_func, (void *)sockets[1]);

	sleep(1);	/* 延时一段时间让子进程先于主进程运行 */

	/* b、接收子进程发送过来的消息 */
	readlen = read(sockets[0], main_buf, BUFFER_SIZE);
	main_buf[readlen] = '\0';
	printf("(2) recv from child thread : %s\n", main_buf);

	/* c、发送一个消息给子进程 */
	printf("(3) send to child thread : %s\n", "TECH-PRO");
	write(sockets[0], "TECH-PRO", sizeof("TECH-PRO"));

	sleep(1);	/* 延时一段等待子进程执行完毕 */

	return 0;
}
编译并运行,结果如下:


二、在父子进程间实现双向通讯

这个例子实现的功能是:编写一个应用程序,实现两个进程,让这两个进程之间实现双向通讯。完整代码如下所示:

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

/* 定义socketpair缓冲区的大小 */
#define SOCKET_BUFFER_SIZE 		((32) * (1024))

#define BUFFER_SIZE		(256)	// 定义一个缓冲区的大小

/*	
 *	定义一个子线程,实现两个进程间的双向通讯
 */
int main(int argc, char *argv[])
{
	int sockets[2];
	int result;
	int bufferSize;

	pthread_t thread;

	char buf[BUFFER_SIZE]= {0};
	int readlen;

	int father_fd;
	int child_fd;

	/* 创建一个socketpair双向通讯的实例 */
	result = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);
	if(-1 == result)
	{
		printf("socketpair error!\n");
		return -1;
	}

	/* 设置socketpair双向通讯各个缓冲区 */
	bufferSize = SOCKET_BUFFER_SIZE;
	setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));

	father_fd = sockets[0];
	child_fd = sockets[1];

	/* 创建子进程 */
	result = fork();
	if(-1 == result)
	{
		printf("fork error!\n");
		return -1;
	}
	else if(0 == result)	// 子进程
	{
		/* a、向主进程发送一个消息 */
		printf("(1) send to main thread : %s\n", "Hello,world!");
		write(child_fd, "Hello,world!", sizeof("Hello,world!"));

		/* d、接收主进程发送的消息 */
		readlen = read(child_fd, buf, BUFFER_SIZE);
		buf[readlen] = '\0';
		printf("(4) recv from main thread : %s\n", buf);
	}
	else if(result > 0)		// 父进程
	{
		sleep(1);	/* 延时一段时间让子进程先于主进程运行 */

		/* b、接收子进程发送过来的消息 */
		readlen = read(father_fd, buf, BUFFER_SIZE);
		buf[readlen] = '\0';
		printf("(2) recv from child thread : %s\n", buf);

		/* c、发送一个消息给子进程 */
		printf("(3) send to child thread : %s\n", "TECH-PRO");
		write(father_fd, "TECH-PRO", sizeof("TECH-PRO"));

		sleep(1);	/* 延时一段等待子进程执行完毕 */
	}

	return 0;
}
编译并运行,结果如下所示:



至此,两个简单的socketpair的小例子实现完毕。本人能力有限,文中有错误或者不合理的地方,请多指教。


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值