背景:像unix或linux下的mysql和php-fpm都有一个xxx.sock文件,它是干嘛的呢?可以研究一下它。
管道由于只能实现具有亲缘进程的进程间通信,使用受到了很大的限制,命名管道解决了这一问题。但是,无论是管道还是命名管道,都只能实现单向通信(在只创建一个管道的情况下)。
使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。这里所指的使用套接字实现进程间通信,是由将通信域指定为PF_UNIX来实现的。该函数的形式如下:
int socket(int domain, int type, int protocol);
socket函数中的domain参数用于指定通信域,domain参数取PF_UNIX时,表示创建UNIX域的套接字。使用PF_UNIX域的套接字可以实现同一机器上的不同进程间的通信。
调用bind函数实现了套接字与地址(这里是文件名)的绑定。bind函数的具体信息如下:
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
其参数my_addr为指向结构体sockaddr_un的指针,该结构体的定义如下:
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family; /*PF_UNIX或AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* 路径名 */
};
在该结构体中,sun_family为AF_UNIX。sun_path是套接字在文件系统中的路径名。
Unix域套接字是通过套接字API实现的简单的协议族。实际上它并不代表一个网络协议;它只能连接到同一台机器上的套接字。它提供了灵活的IPC机制。它的地址是它所在的文件系统的路径名,创建之后套接字就和路径名绑定在一起。用来表示Unix域地址的套接字文件能够使用stat()但是不能通过open()打开,而且应该使用套接字API对它进行操作。
Unix域套接字是面向连接的,每个套接字的连接都建立了一个新的通讯信道。服务器可能同时处理许多连接,但对于每个连接都有不同的文件描述符。这个属性使Unix域套接字能够比命名管道更好的适应IPC任务。
server.c
send.c
gcc server.c -o server
gcc send.c -o send
[root@iZ25dcp92ckZ sock]# ./server
Bind is ok
有client启动后server响应如下:
Recv: Counter is 1
Recv: Counter is 2
Recv: Counter is 3
Recv: Counter is 4
[root@iZ25dcp92ckZ sock]# ./send
Send: Counter is 1
Send: Counter is 2
Send: Counter is 3
Send: Counter is 4
最后,还发现那个设备文件server.sock 不能直接cat去读取,只能stat:
[root@iZ25dcp92ckZ sock]# cat server.sock
cat: server.sock: 没有那个设备或地址
[root@iZ25dcp92ckZ sock]# stat server.sock
文件:"server.sock"
大小:0 块:0 IO 块:4096 套接字
设备:ca01h/51713d Inode:16282 硬链接:1
权限:(0755/srwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2016-04-18 14:11:20.878641353 +0800
最近更改:2016-04-18 14:11:20.878641353 +0800
最近改动:2016-04-18 14:11:20.878641353 +0800
创建时间:-
实践摘录自:http://www.cnblogs.com/hnrainll/archive/2011/12/03/2274973.html
管道由于只能实现具有亲缘进程的进程间通信,使用受到了很大的限制,命名管道解决了这一问题。但是,无论是管道还是命名管道,都只能实现单向通信(在只创建一个管道的情况下)。
使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。这里所指的使用套接字实现进程间通信,是由将通信域指定为PF_UNIX来实现的。该函数的形式如下:
int socket(int domain, int type, int protocol);
socket函数中的domain参数用于指定通信域,domain参数取PF_UNIX时,表示创建UNIX域的套接字。使用PF_UNIX域的套接字可以实现同一机器上的不同进程间的通信。
调用bind函数实现了套接字与地址(这里是文件名)的绑定。bind函数的具体信息如下:
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
其参数my_addr为指向结构体sockaddr_un的指针,该结构体的定义如下:
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family; /*PF_UNIX或AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* 路径名 */
};
在该结构体中,sun_family为AF_UNIX。sun_path是套接字在文件系统中的路径名。
Unix域套接字是通过套接字API实现的简单的协议族。实际上它并不代表一个网络协议;它只能连接到同一台机器上的套接字。它提供了灵活的IPC机制。它的地址是它所在的文件系统的路径名,创建之后套接字就和路径名绑定在一起。用来表示Unix域地址的套接字文件能够使用stat()但是不能通过open()打开,而且应该使用套接字API对它进行操作。
Unix域套接字是面向连接的,每个套接字的连接都建立了一个新的通讯信道。服务器可能同时处理许多连接,但对于每个连接都有不同的文件描述符。这个属性使Unix域套接字能够比命名管道更好的适应IPC任务。
server.c
send.c
gcc server.c -o server
gcc send.c -o send
[root@iZ25dcp92ckZ sock]# ./server
Bind is ok
有client启动后server响应如下:
Recv: Counter is 1
Recv: Counter is 2
Recv: Counter is 3
Recv: Counter is 4
[root@iZ25dcp92ckZ sock]# ./send
Send: Counter is 1
Send: Counter is 2
Send: Counter is 3
Send: Counter is 4
最后,还发现那个设备文件server.sock 不能直接cat去读取,只能stat:
[root@iZ25dcp92ckZ sock]# cat server.sock
cat: server.sock: 没有那个设备或地址
[root@iZ25dcp92ckZ sock]# stat server.sock
文件:"server.sock"
大小:0 块:0 IO 块:4096 套接字
设备:ca01h/51713d Inode:16282 硬链接:1
权限:(0755/srwxr-xr-x) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2016-04-18 14:11:20.878641353 +0800
最近更改:2016-04-18 14:11:20.878641353 +0800
最近改动:2016-04-18 14:11:20.878641353 +0800
创建时间:-
实践摘录自:http://www.cnblogs.com/hnrainll/archive/2011/12/03/2274973.html
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/8643/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
最后编辑: jackxiang 编辑于2016-4-18 14:18
评论列表