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 else123 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用于本机上的进程之间的通信。
只有这样才不会被“不可能”束缚,才能不断超越自我。