Linux网络编程之socket编程(十五)-UNIX域

这篇文章将要学习UNIX域相关知识,包括UNIX域协议特点、UNIX域地址结构、UNIX字节流回射客户/服务、UNIX域套接字编程注意点等。

1.UNIX域协议特点

(1)UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者约是后者的两倍。

(2)UNIX域套接字可以在同一台主机上各进程之间传递描述符。

(3)UNIX域套接字与传统套接字的区别是用路径名来表示协议族的描述。

2.UNIX域地址结构

3.UNIX域字节流回射客户/服务

其基本流程和TCP回射客户/服务是类似的。

  • 服务端设计:

(1)首先,创建一个套接字linstenfd,与TCP/UDP创建套接字不同的是,此时socket函数第一个参数协议家族是AF_UNIX,并且使用流式套接字:
int listenfd;
listenfd = socket(AF_UNIX, SOCK_STREAM, 0);

(2)然后初始化地址结构,其地址结构内需要关注两个成员——sun_family、sun_path:
struct sockaddr_un servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaaddr.sun_path, “test_socket”);

(3)接下来进行bind绑定:
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

(4)绑定完之后进行listen监听:
listen(listenfd, SOMAXCONN);

(5)之后就可以在while循环中接收客户端的连接了,accept之后会返回一个已连接套接字conn,其中accept可以不关心对等方的地址,即,后两个参数置为0:
accept(listenfd, NULL, NULL);

(6)连接建立之后,这里就不使用select或epoll的方式来处理了,直接使用fork子进程的方式来进行处理。其中子进程(pid == 0)来处理通信模块echo_srv(子进程不需要处理监听,所以要close(listenfd));父进程负责监听任务(父进程不需要处理连接,所以close(conn)即可)。

服务端源码:

  • 客户端设计:

(1)类似地,客户端也需要创建一个套接字,协议家族是AF_UNIX。

(2)然后连接对方的地址,所以在这之前需要初始化服务器端的地址。初始化地址之后就可以connect对等方了。
connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));

(3)连接成功之后,就可以进行通信了,封装一个通信模块echo_cli。

客户端源码:

4.UNIX域套接字编程注意事项

(1)bind成功将会创建一个文件,权限为0777 & ~umask

(2)sun_path最好用一个绝对路径
例如,将程序中的“test_socket”改为“/tmp/test_socket”

(3)UNIX域协议支持流式套接口与报式套接口
流式套接口可能会产生粘包问题,接收的时候最好按照协议的方式进行接收,比如封装一个readline方法;报式套接口则不存在粘包问题。

(4)UNIX域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED,这和TCP不同——如果监听队列满,会忽略到来的SYN,这导致对方重传SYN。

发表评论

电子邮件地址不会被公开。 必填项已用*标注