1.1定义
UNIX域socket实现本地进程间通信,需要一个进程作为服务器端,一个进程作为客户端。对于sockaddr_un结构,重点是给它提供一个bind()函数生成的socket类型文件的路径,即sockaddr_un.sun_path的值。并且客户端与服务器端的这个sockaddr_un结构的sun_path是一致的。
经过bind,listen,accept,和connect后,两进程就通过读写socket文件描述符来通信,具体是服务器端读写accept返回的socket文件描述符,客户端读写经过connect处理后的文件描述符。
1.2 使用
1.2.1服务器端通信过程分析
- 调用socket()函数,建立socket对象,指定通信协议为AF_UNIX。
struct sockaddr_un address;
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
address.sun_family = AF_UNIX;
struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX;而sun_path就是本地文件的路径。
- 调用bind()函数,将创建的socket对象与bind()函数产生的那个socket类型的文件server_socket P绑定。
bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) //在客户端调用bind函数
snprintf(address.sun_path, sizeof(address.sun_path)-1, "%s", g_tunnel_path[be_tunnel - 1].path_name); //在服务端绑定所生成socket类型的文件
UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,且已被link,则bind()错误返回。一个套接字只能绑定到一个路径上,同样的,一个路径也只能被一个套接字绑定。 该文件不能打开,也不能由应用程序用于通信,当关闭套接字时,并不自动删除该文件,所以我们必须确保在应用程序终止前,对该文件执行解除链接操作(unlink(path)),或删除该文件。
- 调用listen()函数,使socket对象处于监听状态,并设置监听队列大小。
- 服务器端监听客户端的连接请求,在客户端发出请求后,服务端使用accept()函数接收请求,返回新文件描述符,从而建立连接。
- 服务器端调用read()函数接收数据(开始处于阻塞状态,等待客户端发送数据,因此,客户端在编程是需要首先发送数据,接收到数据后,输出接收到的数据)。
- 调用write()函数发送数据到客户端。
- 通信完成后,调用close()函数关闭socket对象;unlink(sockaddr_un.sun_path)。
1.2.2客户端通信过程分析
- 调用socket()函数,建立socket对象,指定相同通信协议。
- 客户端调用connect()函数,向服务器端发起连接请求。
- 在得到服务器端允许后,首先调用write()函数向服务器端发送消息(因服务器端循环体中首先是接收数据)。
- 调用read()函数接收数据。
- 通信完成后,调用close()函数关闭socket对象。