From: http://www.cnblogs.com/xuxu8511/p/3217444.html
server.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/socket.h> 5 #include <sys/un.h> 6 #include <unistd.h> 7 #include <signal.h> 8 #include <sys/epoll.h> 9 #include <errno.h> 10 11 #define UNIX_DOMAIN "/tmp/UNIX.domain" 12 13 14 void handler(){ 15 16 printf("clean program start\n"); 17 //unlink(UNIX_DOMAIN); 18 remove(UNIX_DOMAIN); 19 printf("clean end.\n"); 20 } 21 22 int main(void) 23 { 24 int lsn_fd, apt_fd; 25 struct sockaddr_un srv_addr; 26 struct sockaddr_un clt_addr; 27 socklen_t clt_len; 28 int ret; 29 int i; 30 char recv_buf[1024]; 31 char send_buf[1024]; 32 33 signal(SIGTERM,handler); 34 35 //create epoll 36 int epfd,eventfd; 37 struct epoll_event ev,events[1024]; 38 39 epfd = epoll_create(1024); 40 41 //create socket to bind local IP and PORT 42 lsn_fd = socket(AF_UNIX, SOCK_STREAM, 0); 43 ev.data.fd = lsn_fd; 44 ev.events = EPOLLIN|EPOLLET; 45 46 epoll_ctl(epfd,EPOLL_CTL_ADD,lsn_fd,&ev); 47 48 if(lsn_fd < 0) 49 { 50 perror("can't create communication socket!"); 51 return 1; 52 } 53 54 //create local IP and PORT 55 srv_addr.sun_family = AF_UNIX; 56 strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1); 57 //unlink(UNIX_DOMAIN); 58 59 //bind sockfd and sockaddr 60 ret = bind(lsn_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); 61 if(ret == -1) 62 { 63 perror("can't bind local sockaddr!"); 64 close(lsn_fd); 65 unlink(UNIX_DOMAIN); 66 return 1; 67 } 68 69 //listen lsn_fd, try listen 5 70 71 ret = listen(lsn_fd, 5); 72 if(ret == -1) 73 { 74 perror("can't listen client connect request"); 75 close(lsn_fd); 76 unlink(UNIX_DOMAIN); 77 78 return 1; 79 } 80 81 clt_len = sizeof(clt_addr); 82 while(1) 83 { 84 int nfds = epoll_wait(epfd,events,1024,100); 85 int i=0; 86 for(i=0;i<nfds;++i) 87 { 88 if(events[i].data.fd == lsn_fd) 89 { 90 apt_fd = accept(lsn_fd, (struct sockaddr*)&clt_addr, &clt_len); 91 if(apt_fd < 0){ 92 perror("can't listen client connect request"); 93 close(lsn_fd); 94 unlink(UNIX_DOMAIN); 95 return 1; 96 } 97 char lines[256]; 98 sprintf(lines,"server data to client\n"); 99 write(apt_fd, lines, 256); 100 101 ev.data.fd = apt_fd; 102 ev.events = EPOLLIN|EPOLLET; 103 104 epoll_ctl(epfd,EPOLL_CTL_ADD,apt_fd,&ev); 105 106 } 107 else if (events[i].events & EPOLLIN) 108 //write数据 109 { 110 printf("EPOLLIN\n"); 111 if( (eventfd = events[i].data.fd) < 0 ) 112 continue; 113 114 int n=0,ret=0 ; 115 char line[256]; 116 if ((ret = read(eventfd,line,256)) < 0){ 117 118 if(errno == ECONNRESET){ 119 close(eventfd); 120 events[i].data.fd = -1; 121 } 122 else 123 printf("readline error\n"); 124 } 125 else if( ret == 0){ 126 close(eventfd); 127 events[i].data.fd = -1; 128 } 129 else if( ret > 0 ) 130 { 131 line[ret] = '\0'; 132 printf("%s",line); 133 while( ( ret = read(eventfd,line,256)) >0) 134 { 135 line[ret] = '\0'; 136 printf("%s",line); 137 } 138 printf("\n"); 139 } 140 } 141 else if (events[i].events & EPOLLOUT){ 142 //写出的数据,在EPOLLIN处理中设置fd的events为EPOLLOUT|EPOLLET时,即触发该事件 143 int eventfd = events[i].data.fd; 144 char line[256]; 145 write(eventfd,line,256); 146 147 ev.data.fd = eventfd; 148 ev.events = EPOLLIN | EPOLLET; 149 150 epoll_ctl ( epfd, EPOLL_CTL_ADD, eventfd, &ev); 151 } 152 } 153 } 154 155 close(apt_fd); 156 close(lsn_fd); 157 unlink(UNIX_DOMAIN); 158 return 0; 159 }
client.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/socket.h> 4 #include <sys/un.h> 5 #include <unistd.h> 6 7 #define UNIX_DOMAIN "/tmp/UNIX.domain" 8 9 int main(void) 10 { 11 int connect_fd; 12 struct sockaddr_un srv_addr; 13 char snd_buf[256]; 14 char rcv_buf[256]; 15 int ret; 16 int i; 17 connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); 18 19 if(connect_fd < 0) 20 { 21 perror("client create socket failed"); 22 return 1; 23 } 24 srv_addr.sun_family = AF_UNIX; 25 strcpy(srv_addr.sun_path, UNIX_DOMAIN); 26 ret = connect(connect_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); 27 28 if(ret == -1) 29 { 30 perror("connect to server failed!"); 31 close(connect_fd); 32 unlink(UNIX_DOMAIN); 33 return 1; 34 } 35 36 memset(rcv_buf, 0, 256); 37 int rcv_num = read(connect_fd, rcv_buf, sizeof(rcv_buf)); 38 printf("receive message from server (%d) :%s\n", rcv_num, rcv_buf); 39 40 memset(snd_buf, 0, 256); 41 strcpy(snd_buf, "message from client"); 42 printf("sizeof(snd_buf): %d\n", sizeof(snd_buf)); 43 44 printf("send data to server... ...\n"); 45 for(i = 0; i < 4; i++) 46 { 47 write(connect_fd, snd_buf, sizeof(snd_buf)); 48 } 49 printf("send end!\n"); 50 close(connect_fd); 51 return 0; 52 53 }
与网络的socket通信的区别,即socket地址有些区别,其他的一样。
sockaddr_in用于网络的socket通信,sockaddr_un用于本机上的进程之间的通信。