关于UNIX Domain Socket 编程
2015-06-25 14:26
393 查看
进程间通信,通讯机制很快会从大脑中跑出一连串方法出来:共享内存、管道、有名管道、信号量、套接字(socket)等。提到socket 大家很快会想到的是 address family
为AF_INET ,type为SOCK_DGRAM或SOCK_STREAM 。还有一种接触少的没有接触的人很多时候会忽略:UNIX Domain Socket 。解决同样的通信问题,但在效率上与可靠性上它(UNIX
Domain Socket)会略胜一筹:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。 这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX
Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
UNIX Domain Socket 的type同样可以选择SOCK_DGRAM或SOCK_STREAM ,address family 指定为AF_UNIX,protocol参数仍然指定为0即可。UNIX
Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口 号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存 在,则bind()错误返回。int fd_server_listen(const char *filepath)// src >> "/var/fd.socket"
{
int sockfd;
struct sockaddr_un unix_addr;
/* create a Unix domain stream socket */
if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
printf("domain socket server initialized fail!\n");
return -1;
}
/* in case it already exists */
unlink(filepath);
/* fill in socket address structure */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, filepath);
/* bind the name to the descriptor */
if(bind(sockfd, (struct sockaddr *)&unix_addr, SUN_LEN(&unix_addr)) < 0)
{
printf("domain socket server bind fail!\n");
goto error;
}
if(chmod(filepath, S_IRUSR|S_IWUSR) < 0)
{
printf("chmod fail:%s\n", filepath);
goto error;
}
/* tell kernel we're a server */
if(listen(sockfd, 10) < 0)
{
printf("domain socket server listen fail!\n");
goto error;
}
return sockfd;
error:
close(sockfd);
return -1;
}
的路径应该是服务端src一样的。
int InitSocket(int *cli_sockfd)
{
struct sockaddr_un address;
int sockfd;
int len;
/*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
printf("InitSocket ::failed");
return 1;
}
//addr
address.sun_family = AF_UNIX;
strcpy (address.sun_path, HYCGI_SERVSOCK_PATH);
len = OFFSETOF(struct sockaddr_un, sun_path) + strlen(HYCGI_SERVSOCK_PATH);
/*向服务器发送连接请求*/
if (-1 == connect (sockfd, (struct sockaddr *)&address, len) )
{
close(sockfd);
char buf[64];
sprintf(buf,"InitSocket::connect errno = %d",errno);
printf("%s"buf);
return 2;
}
*cli_sockfd = sockfd;
return 0;
}关于UNIX
Domain Socket 编程,以上是最基础的过程,个人感觉无论是管道还是这个,还是共享内存,抓住编程的初衷:数据的有效传递。相关的,对于多个线程间如何跟服务端通信,还需要设置相关定制协议即可。
为AF_INET ,type为SOCK_DGRAM或SOCK_STREAM 。还有一种接触少的没有接触的人很多时候会忽略:UNIX Domain Socket 。解决同样的通信问题,但在效率上与可靠性上它(UNIX
Domain Socket)会略胜一筹:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。 这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX
Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
UNIX Domain Socket 的type同样可以选择SOCK_DGRAM或SOCK_STREAM ,address family 指定为AF_UNIX,protocol参数仍然指定为0即可。UNIX
Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口 号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存 在,则bind()错误返回。int fd_server_listen(const char *filepath)// src >> "/var/fd.socket"
{
int sockfd;
struct sockaddr_un unix_addr;
/* create a Unix domain stream socket */
if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
printf("domain socket server initialized fail!\n");
return -1;
}
/* in case it already exists */
unlink(filepath);
/* fill in socket address structure */
memset(&unix_addr, 0, sizeof(unix_addr));
unix_addr.sun_family = AF_UNIX;
strcpy(unix_addr.sun_path, filepath);
/* bind the name to the descriptor */
if(bind(sockfd, (struct sockaddr *)&unix_addr, SUN_LEN(&unix_addr)) < 0)
{
printf("domain socket server bind fail!\n");
goto error;
}
if(chmod(filepath, S_IRUSR|S_IWUSR) < 0)
{
printf("chmod fail:%s\n", filepath);
goto error;
}
/* tell kernel we're a server */
if(listen(sockfd, 10) < 0)
{
printf("domain socket server listen fail!\n");
goto error;
}
return sockfd;
error:
close(sockfd);
return -1;
}
int client_fd = accept(sockfd, NULL, NULL);关于编程客户端,有关小小的细节注意下,就是socket的相应的路径需要相同例如:HYCGI_SERVSOCK_PATH
的路径应该是服务端src一样的。
int InitSocket(int *cli_sockfd)
{
struct sockaddr_un address;
int sockfd;
int len;
/*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
{
printf("InitSocket ::failed");
return 1;
}
//addr
address.sun_family = AF_UNIX;
strcpy (address.sun_path, HYCGI_SERVSOCK_PATH);
len = OFFSETOF(struct sockaddr_un, sun_path) + strlen(HYCGI_SERVSOCK_PATH);
/*向服务器发送连接请求*/
if (-1 == connect (sockfd, (struct sockaddr *)&address, len) )
{
close(sockfd);
char buf[64];
sprintf(buf,"InitSocket::connect errno = %d",errno);
printf("%s"buf);
return 2;
}
*cli_sockfd = sockfd;
return 0;
}关于UNIX
Domain Socket 编程,以上是最基础的过程,个人感觉无论是管道还是这个,还是共享内存,抓住编程的初衷:数据的有效传递。相关的,对于多个线程间如何跟服务端通信,还需要设置相关定制协议即可。
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- Linux VS Unix:Linux欲一统天下 Unix不死
- 肯特·贝克:改变人生的代码整理魔法
- 你应该学习哪种编程语言?
- [转]我们需要一种其他人能使用的编程语言
- DB2编程序技巧(1)
- DB2编程序技巧 (四)
- 女人VS编程_国庆快乐
- DB2编程序技巧 (六)
- DB2编程序技巧 (三)
- DB2编程序技巧 (九)
- DB2编程序技巧 (七)
- DB2编程序小小技巧
- DB2编程序技巧 (五)
- DB2编程序技巧 (一)
- DB2编程序技巧 (八)
- DB2编程序技巧 (十)
- VBS基础编程教程 (第1篇)
- VBS基础编程教程 (第3篇)