对命名的Unix Domain Socket的认识(一)
2013-01-04 13:43
471 查看
命名的Unix Domain Socket,是相对于未命名的Unix Domain Socket(socketpair)而言的。Unix Domain Socket 主要用于进程间通信,和网络Socket 相比它不依赖于具体的网络协议。它可以将应用层的数据从一个进程拷贝到另一个进程。它主要分为面向流和面向数据包两种模式(类似于TCP和UDP)。
命名的Unix Domain Socket 需要绑定到一个地址上,只是这个地址不是主机地址,而是一个文件路径,相关结构体是struct sockaddr_un(网络Socket是struct sockaddr_in)。
具体实现流程如下:
1.服务端: 创建Socket->绑定Socket->监听Socket->接收客户端连接->接收/发送数据
2.客户端: 创建Socket->绑定Socket->连接服务端Socket->发送/接收数据
命名的Unix Domain Socket 的address family 是AF_UNIX,它并不需要IP地址和端口号。它的地址就是一个具体的文件的路径,其客户端也需要绑定(调用bind函数)让服务端识别客户端。
一般而言,客户端绑定时的文件名称为客户端所在进程的进程号,这样有利于唯一标识该进程。
服务端和客户端在绑定时,Socket 绑定的文件如果已经存在,那么绑定就会失败,在绑定前,可以将对应文件删除。
简单而言,命名的Unix Domain Socket 就是将Socket 绑定到了一个文件上。具体实例如下,这个实例没有具体的数据交互。
服务端 server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stddef.h>
#define NAME "/home/test/testsocket.socket"
int main(void){
int sd,cd,result,sin_size;
struct sockaddr_un un;
sd=socket(AF_UNIX,SOCK_STREAM,0);
if(sd==-1){
printf("create unix domain socket failed\n");
return 0;
}
printf("create unix domain socket successfully!\n");
unlink(NAME);
memset(&un,0,sizeof(struct sockaddr_un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,NAME);
int len=offsetof(struct sockaddr_un,sun_path)+strlen(NAME);
if(bind(sd,(struct sockaddr *)&un,len)<0){
printf("bind unix domain socket error!\n");
return 0;
}
printf("bind unix domain socket successfully!\n");
if(listen(sd,10)<0){
printf("listen unix domain socket error!]n");
return 0;
}
printf("listen unix domain socket successfully!\n");
while(1){
sin_size=sizeof(struct sockaddr_un);
result=accept(sd,(struct sockaddr *)&un,&sin_size);
if(result<0){
return -1;
}
printf("accept client request\n");
close(result);
}
close(sd);
return 0;
}
客户端 client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#define NAME "/home/test/testsocket.socket"
#define CLI_PATH "/home/test/"
#define CLI_PERM S_IRWXU
int main(void){
int cd,length;
struct sockaddr_un un;
cd=socket(AF_UNIX,SOCK_STREAM,0);
if(cd==-1){
printf("create unix domain socket fail\n");
return -1;
}
printf("create client unix domain socket successfully\n");
memset(&un,0,sizeof(un));
un.sun_family=AF_UNIX;
sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
length=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);
unlink(un.sun_path);
if(bind(cd,(struct sockaddr *)&un,length)<0){
printf("bind client unix domain socket fail\n");
return -1;
}
printf("bind client unix domain socket successfully\n");
printf("sun_path is %s\n",un.sun_path);
if(chmod(un.sun_path,CLI_PERM)<0){
printf("chmod fail \n");
return -1;
}
memset(&un,0,sizeof(un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,NAME);
length=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);
if(connect(cd,(struct sockaddr *)&un,length)==-1){
printf("connect unix domain socket failed\n");
return -1;
}
printf("connect remote socket successfully\n");
close(cd);
return 0;
}
命名的Unix Domain Socket 需要绑定到一个地址上,只是这个地址不是主机地址,而是一个文件路径,相关结构体是struct sockaddr_un(网络Socket是struct sockaddr_in)。
具体实现流程如下:
1.服务端: 创建Socket->绑定Socket->监听Socket->接收客户端连接->接收/发送数据
2.客户端: 创建Socket->绑定Socket->连接服务端Socket->发送/接收数据
命名的Unix Domain Socket 的address family 是AF_UNIX,它并不需要IP地址和端口号。它的地址就是一个具体的文件的路径,其客户端也需要绑定(调用bind函数)让服务端识别客户端。
一般而言,客户端绑定时的文件名称为客户端所在进程的进程号,这样有利于唯一标识该进程。
服务端和客户端在绑定时,Socket 绑定的文件如果已经存在,那么绑定就会失败,在绑定前,可以将对应文件删除。
简单而言,命名的Unix Domain Socket 就是将Socket 绑定到了一个文件上。具体实例如下,这个实例没有具体的数据交互。
服务端 server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stddef.h>
#define NAME "/home/test/testsocket.socket"
int main(void){
int sd,cd,result,sin_size;
struct sockaddr_un un;
sd=socket(AF_UNIX,SOCK_STREAM,0);
if(sd==-1){
printf("create unix domain socket failed\n");
return 0;
}
printf("create unix domain socket successfully!\n");
unlink(NAME);
memset(&un,0,sizeof(struct sockaddr_un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,NAME);
int len=offsetof(struct sockaddr_un,sun_path)+strlen(NAME);
if(bind(sd,(struct sockaddr *)&un,len)<0){
printf("bind unix domain socket error!\n");
return 0;
}
printf("bind unix domain socket successfully!\n");
if(listen(sd,10)<0){
printf("listen unix domain socket error!]n");
return 0;
}
printf("listen unix domain socket successfully!\n");
while(1){
sin_size=sizeof(struct sockaddr_un);
result=accept(sd,(struct sockaddr *)&un,&sin_size);
if(result<0){
return -1;
}
printf("accept client request\n");
close(result);
}
close(sd);
return 0;
}
客户端 client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#define NAME "/home/test/testsocket.socket"
#define CLI_PATH "/home/test/"
#define CLI_PERM S_IRWXU
int main(void){
int cd,length;
struct sockaddr_un un;
cd=socket(AF_UNIX,SOCK_STREAM,0);
if(cd==-1){
printf("create unix domain socket fail\n");
return -1;
}
printf("create client unix domain socket successfully\n");
memset(&un,0,sizeof(un));
un.sun_family=AF_UNIX;
sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
length=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);
unlink(un.sun_path);
if(bind(cd,(struct sockaddr *)&un,length)<0){
printf("bind client unix domain socket fail\n");
return -1;
}
printf("bind client unix domain socket successfully\n");
printf("sun_path is %s\n",un.sun_path);
if(chmod(un.sun_path,CLI_PERM)<0){
printf("chmod fail \n");
return -1;
}
memset(&un,0,sizeof(un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,NAME);
length=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);
if(connect(cd,(struct sockaddr *)&un,length)==-1){
printf("connect unix domain socket failed\n");
return -1;
}
printf("connect remote socket successfully\n");
close(cd);
return 0;
}
相关文章推荐
- 本地socket unix domain socket .
- unix domain socket 使用时crash
- Linux下的IPC-UNIX Domain Socket
- UNIX Domain Socket IPC (sockaddr_un )
- unix domain socket VS named pipes
- 利用UNIX Domain Socket实现进程间通信(IPC)
- 本地socket unix domain socket
- UNIX Domain Socket IPC
- 本地socket unix domain socket
- UNIX Domain Socket IPC (sockaddr_un )
- UNIX Domain Socket IPC - blueliuyun的专栏 - 博客频道 - CSDN.NET
- 使用psql命令基于udp(unix-domain-socket)协议连接postgresql数据库
- UNIX Domain Socket IPC
- nginx通过TCP以及unix-domain-socket连接fastcgi方式对比
- IPC of UNIX Domain Socket基础程序实现
- 关于UNIX Domain Socket 编程
- (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误
- Unix domain socket和memcached
- Linux下的IPC-UNIX Domain Socket【转】
- (unix domain socket)使用udp发送>=128K的消息会报ENOBUFS的错误