48.Linux网络编程--Unix 域套接字

一.Unix域套接字的产生原因及特性

1.产生原因:

在之前的学习中我们学习了网络套接字,实现了不同主机间的进程通讯,同时为了保证数据传输的可靠性,网络套接字中增加了许多校验,应答,序列号等机制,但是假如我们想要实现本机两个进程间通讯的话,使用同样的方法行不行??当然行,但是大材小用了,本来本地进程间通讯就比较可靠,不用这么麻烦,为了提高效率,出现了Unix域套接字。

2.特性

  •  UNIX域套接字用于在同一台计算机上运行的进程之间的通信
  • UNIX域套接字提供流和数据报两种接口。UNIX域数据报服务是可靠的,既不会丢失消息也不会传递出错。UNIX域套接          字是套接字和管道之间的混合物
  • UNIX域套接字域传统套接字的区别是用路径名表示协议族的描述
  • UNIX域套接字可以在同一台主机上各进程之间传递文件描述符

3.进程间通讯机制比较

我们知道了它是是一种进程间通讯的方式,常用于前后台进程通信,但是我们在之前的学习中知道进程间的通讯机制还有有管道,共享内存,信号量,信号,消息队列等。

回顾一下进程间通讯机制:

1》进程间数据共享

  • 管道,消息队列,共享内存,unix 域套接字
  • 易用性:消息队列 > unix 域套接字 > 管道 > 共享内存(配合信号量使用)
  • 效率:共享内存 > unix 域套接字  > 管道 > 消息队列
  • 常用:共享内存,unix 域套接字

2》异步通讯

  • 信号

3》 同步和互斥

  • 信号量

从上面比较也可以看出和其他进程间通信方式相比使用方便、效率更高

 

4.unix 域套接字编程

unix 域套接字分为流式套接字和用户数据报套接字

      

 

看着和我们之前的socket编程基本上没有什么区别,但是注意的是之前我们填充的是网络地址(IP和端口),现在要用本地地址,我们需要填充的结构体是sockaddr_un.

文件名要事先不存在,路径一般给绝对路径。

实现原理

借助文件来实现进程间通讯。

看个实例我们就知道怎么写了:

server.c

    #define UNIX_DOMAIN_FILE "/tmp/my_domain_file.1"
      
     /* 1. 创建socket fd */
	if ((fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) { //基于本地的TCP通信
		perror ("socket");
		exit (1);
	}

	/* 允许绑定地址快速重用 */
	int b_reuse = 1;
	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
	
	/* 2.1 填充sockaddr_un结构体变量 */
	struct sockaddr_un sun;
	bzero(&sun, sizeof(sun));
	sun.sun_family = AF_LOCAL;
	
	/* 如果UNIX_DOMAIN_FILE所指向的文件存在,则删除 */
	if(!access(UNIX_DOMAIN_FILE, F_OK)) {
		unlink(UNIX_DOMAIN_FILE);
	}
	strncpy(sun.sun_path, UNIX_DOMAIN_FILE, strlen( UNIX_DOMAIN_FILE));
	

	/*2.2 绑定 */
	if (bind (fd, (struct sockaddr *) &sun, sizeof (sun)) < 0) {
		perror ("bind");
		exit (1);
	}

	/*3. 调用listen()把主动套接字变成被动套接字 */
	if (listen (fd, BACKLOG) < 0) {
		perror ("listen");
		exit (1);
	}
	printf ("Unix domain server starting....OK!\n");
	int newfd = -1;
	/*4. 阻塞等待客户端连接请求 */
	while(1) {
		if ((newfd = accept (fd, NULL,NULL)) < 0) {
                        perror ("accept");
                        break;
                }
		
	}		

client.c

    /* 1. 创建socket fd */
	if ((fd = socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) {
		perror ("socket");
		exit (1);
	}

	/*2.连接服务器 */

	/*2.1 填充struct sockaddr_un结构体变量 */
	bzero (&sun, sizeof (sun));
	sun.sun_family = AF_LOCAL;
	
	/*确保UNIX_DOMAIN_FILE要先存在并且可写,不存在则退出 */
	if( access(UNIX_DOMAIN_FILE, F_OK| W_OK) < 0){
		exit(1);
	}
	strncpy(sun.sun_path, UNIX_DOMAIN_FILE, strlen( UNIX_DOMAIN_FILE));


	if (connect (fd, (struct sockaddr *) &sun, sizeof (sun)) < 0) {
		perror ("connect");
		exit (1);
	}

	printf ("Unix domain Client staring...OK!\n");

大概的使用方法就是这样的,在什么时候用什么进程通讯,灵活的选用和程序的一些防护,需要慢慢的去学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值