网络编程一<线程间通信的方法之UNIX域套接字>
来源:互联网 发布:mac系统官方下载地址 编辑:程序博客网 时间:2024/06/10 08:37
socket API原本是为网络通讯设计的,后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。
虽然网络socket也可用于同一台主机的进程间通讯,但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。
UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIXDomain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
我们先来看下地址格式:
<span style="font-family:FangSong_GB2312;font-size:18px;">struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* pathname */ };</span>
UNIX Domain Socket与因特网域套接字socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,因特网域套接字socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径。
创建套接字的函数如下:
<span style="font-family:FangSong_GB2312;font-size:18px;">#include <sys/socket.h> int socket(int domain, int type, int protocol);/*成功返回文件(套接字)描述符,出错返回-1*/ </span>
其中的domain参数用于指定通信域,如果为PF_UNIX的话,那么创建unix域套接字,type套接字类型主要有面向连接的字节流SOCK_STREAM和长度固定的无连接的不可靠数据报报文传递SOCK_DGRAM。参数protocol通常为0。
下面有两组代码(第一组type为SOCK_STREAM的服务端和客户端,第二组为SOCK_DGRAM)。
第一组server.c:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h> #define UNIX_DOMAIN "UNIX.domain"int main(void){ socklen_t clt_addr_len; int listen_fd; int com_fd; int ret; int i; static char recv_buf[1024]; int len; struct sockaddr_un clt_addr; struct sockaddr_un srv_addr; listen_fd=socket(PF_UNIX,SOCK_STREAM,0); if(listen_fd<0) { perror("cannot create communication socket"); return 1; } //set server addr_param srv_addr.sun_family=AF_UNIX; strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1); unlink(UNIX_DOMAIN); //bind sockfd & addr ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr)); if(ret==-1) { perror("cannot bind server socket"); close(listen_fd); unlink(UNIX_DOMAIN); return 1; } //listen sockfd ret=listen(listen_fd,1); if(ret==-1) { perror("cannot listen the client connect request"); close(listen_fd); unlink(UNIX_DOMAIN); return 1; } //have connect request use accept len=sizeof(clt_addr); com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len); if(com_fd<0) { perror("cannot accept client connect request"); close(listen_fd); unlink(UNIX_DOMAIN); return 1; } //read and printf sent client info printf("/n=====info=====/n"); for(i=0;i<4;i++) { memset(recv_buf,0,1024); int num=read(com_fd,recv_buf,sizeof(recv_buf)); printf("Message from client (%d)) :%s/n",num,recv_buf); } close(com_fd); close(listen_fd); unlink(UNIX_DOMAIN); return 0;}client.c:
#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define UNIX_DOMAIN "UNIX.domain"int main(void){ int connect_fd; int ret; char snd_buf[1024]; int i; static struct sockaddr_un srv_addr;//creat unix socket connect_fd=socket(PF_UNIX,SOCK_STREAM,0); if(connect_fd<0) { perror("cannot create communication socket"); return 1; } srv_addr.sun_family=AF_UNIX; strcpy(srv_addr.sun_path,UNIX_DOMAIN);//connect server ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr)); if(ret==-1) { perror("cannot connect to the server"); close(connect_fd); return 1; } memset(snd_buf,0,1024); strcpy(snd_buf,"message from client");//send info server for(i=0;i<4;i++) write(connect_fd,snd_buf,sizeof(snd_buf)); close(connect_fd); return 0;}
第二组server.c:
/* * Demo how to implement a simple Local server */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define MAXLINE 50#define IPC_PATH "unix_local_socket"typedef struct sockaddr SA;int main(int argc, char **argv){ intsockfd;struct sockaddr_un local_addr, remote_addr;socklen_tremote_len;charbuf_rcv[MAXLINE];ssize_trcvlen;charbuf_snd[MAXLINE] = "Welcome to UDP Server"; /* step1: create socket * note the socket is creaed as type of SOCK_DGRAM to * work in UDP */if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {perror("socket failed");exit(-1);}/* unlink may return error when the file does not exist, so * we just ignore the return value */ unlink(IPC_PATH);/* step2: bind the sockect to */bzero(&local_addr, sizeof(local_addr));local_addr.sun_family = AF_UNIX;strcpy (local_addr.sun_path, IPC_PATH);if (bind(sockfd, (SA *) &local_addr, sizeof(local_addr)) < 0) {perror("bind failed");exit(-1);}remote_addr = local_addr;for (;;) {/* step3: recvfrom */bzero(buf_rcv, sizeof(buf_rcv)); /* clean up buffer to receive data */remote_len = sizeof(remote_addr);if ((rcvlen = recvfrom(sockfd, buf_rcv, sizeof(buf_rcv), 0, NULL, NULL)) < 0) {perror("recvfrom failed");exit(-1);}if (rcvlen == MAXLINE) buf_rcv[MAXLINE-1] = 0x00; /* in case of overflow */printf("recvfrom successed: %s\n", buf_rcv);break; /* break when receive the data from the client */}return 0;}
client.c:
/* * Demo how to implement a simple Local client */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#define MAXLINE 50#define IPC_PATH "unix_local_socket"typedef struct sockaddr SA;int main(int argc, char **argv){ intsockfd, nbyte;structsockaddr_un remote_addr;charbuf_snd[MAXLINE] = "Hello from UDP client";/* step1: create socket * note the socket is creaed as type of SOCK_DGRAM to * work in UDP */ if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {perror("socket failed");exit(-1);}/* step2: directly send w/o bind */bzero(&remote_addr, sizeof(remote_addr));remote_addr.sun_family = AF_UNIX;strcpy (remote_addr.sun_path, IPC_PATH);if (-1 == sendto(sockfd, buf_snd, sizeof(buf_snd), 0, (SA *)&remote_addr, sizeof(remote_addr))) {perror("sendto failed");exit(-1);}printf("C> recvfrom begin ...\n"); if ((nbyte = recvfrom(sockfd, buf, MAXLINE, 0, NULL, NULL)) < 0) {perror("C> recvfrom error");exit(-1);}return 0;}
0 0
- 网络编程一<线程间通信的方法之UNIX域套接字>
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 简单TCP Socket 通信
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 简单UDP Socket 通信
- Unix网络编程 之 基本套接字调用(一)
- 《网络编程》Unix 域套接字
- 网络编程练习-unix域套接字
- unix域套接字的UDP网络编程
- unix环境IPC编程套接字(一,TCP通信实例
- UNIX网络编程-tcp套接字编程一
- UNIX网络编程卷一:第十五章 Unix域套接字
- UNIX网络编程:套接字
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 非阻塞的Socket通信Select模型(多路复用), 实用Socket通信模板。
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 非阻塞的Socket通信Poll模型(多路复用), 实用Socket通信模板
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 非阻塞的Socket通信EPoll模型(多路复用), 实用Socket通信模板
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 非阻塞的Socket通信EPoll模型(多路复用), 实用Socket通信模板
- Unix网络编程之基本TCP套接字编程
- unix网络编程之套接字编程简介
- UNIX网络编程卷一:套接字联网API-整理
- 单链表的查找操作
- goto语句是一种无条件转移语句
- 单链表的删除
- 单链表的定位操作
- 递归的原理的验证程序!!
- 网络编程一<线程间通信的方法之UNIX域套接字>
- 用堆栈实现括号配对检测的程序
- 循环队列的数组实现!!
- 开灯问题的求解!
- 双链表的学习的操作的实现,带源程…
- 蛇形数组输出的算法--ACM题目
- 【转载】【春节特刊】大小城市双城…
- C++类和结构的区别
- 搜索的学习和调试,包括深度搜索和…