epoll实现linux进程通信
2013-07-26 16:52
204 查看
server.c
client.c
与网络的socket通信的区别,即socket地址有些区别,其他的一样。
sockaddr_in用于网络的socket通信,sockaddr_un用于本机上的进程之间的通信。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <signal.h> #include <sys/epoll.h> #include <errno.h> #define UNIX_DOMAIN "/tmp/UNIX.domain" void handler(){ printf("clean program start\n"); //unlink(UNIX_DOMAIN); remove(UNIX_DOMAIN); printf("clean end.\n"); } int main(void) { int lsn_fd, apt_fd; struct sockaddr_un srv_addr; struct sockaddr_un clt_addr; socklen_t clt_len; int ret; int i; char recv_buf[1024]; char send_buf[1024]; signal(SIGTERM,handler); //create epoll int epfd,eventfd; struct epoll_event ev,events[1024]; epfd = epoll_create(1024); //create socket to bind local IP and PORT lsn_fd = socket(AF_UNIX, SOCK_STREAM, 0); ev.data.fd = lsn_fd; ev.events = EPOLLIN|EPOLLET; epoll_ctl(epfd,EPOLL_CTL_ADD,lsn_fd,&ev); if(lsn_fd < 0) { perror("can't create communication socket!"); return 1; } //create local IP and PORT srv_addr.sun_family = AF_UNIX; strncpy(srv_addr.sun_path, UNIX_DOMAIN, sizeof(srv_addr.sun_path) - 1); //unlink(UNIX_DOMAIN); //bind sockfd and sockaddr ret = bind(lsn_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); if(ret == -1) { perror("can't bind local sockaddr!"); close(lsn_fd); unlink(UNIX_DOMAIN); return 1; } //listen lsn_fd, try listen 5 ret = listen(lsn_fd, 5); if(ret == -1) { perror("can't listen client connect request"); close(lsn_fd); unlink(UNIX_DOMAIN); return 1; } clt_len = sizeof(clt_addr); while(1) { int nfds = epoll_wait(epfd,events,1024,100); int i=0; for(i=0;i<nfds;++i) { if(events[i].data.fd == lsn_fd) { apt_fd = accept(lsn_fd, (struct sockaddr*)&clt_addr, &clt_len); if(apt_fd < 0){ perror("can't listen client connect request"); close(lsn_fd); unlink(UNIX_DOMAIN); return 1; } char lines[256]; sprintf(lines,"server data to client\n"); write(apt_fd, lines, 256); ev.data.fd = apt_fd; ev.events = EPOLLIN|EPOLLET; epoll_ctl(epfd,EPOLL_CTL_ADD,apt_fd,&ev); } else if (events[i].events & EPOLLIN) //write数据 { printf("EPOLLIN\n"); if( (eventfd = events[i].data.fd) < 0 ) continue; int n=0,ret=0 ; char line[256]; if ((ret = read(eventfd,line,256)) < 0){ if(errno == ECONNRESET){ close(eventfd); events[i].data.fd = -1; } else printf("readline error\n"); } else if( ret == 0){ close(eventfd); events[i].data.fd = -1; } else if( ret > 0 ) { line[ret] = '\0'; printf("%s",line); while( ( ret = read(eventfd,line,256)) >0) { line[ret] = '\0'; printf("%s",line); } printf("\n"); } } else if (events[i].events & EPOLLOUT){ //写出的数据,在EPOLLIN处理中设置fd的events为EPOLLOUT|EPOLLET时,即触发该事件 int eventfd = events[i].data.fd; char line[256]; write(eventfd,line,256); ev.data.fd = eventfd; ev.events = EPOLLIN | EPOLLET; epoll_ctl ( epfd, EPOLL_CTL_ADD, eventfd, &ev); } } } close(apt_fd); close(lsn_fd); unlink(UNIX_DOMAIN); return 0; }
client.c
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #define UNIX_DOMAIN "/tmp/UNIX.domain" int main(void) { int connect_fd; struct sockaddr_un srv_addr; char snd_buf[256]; char rcv_buf[256]; int ret; int i; connect_fd = socket(AF_UNIX, SOCK_STREAM, 0); if(connect_fd < 0) { perror("client create socket failed"); return 1; } srv_addr.sun_family = AF_UNIX; strcpy(srv_addr.sun_path, UNIX_DOMAIN); ret = connect(connect_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); if(ret == -1) { perror("connect to server failed!"); close(connect_fd); unlink(UNIX_DOMAIN); return 1; } memset(rcv_buf, 0, 256); int rcv_num = read(connect_fd, rcv_buf, sizeof(rcv_buf)); printf("receive message from server (%d) :%s\n", rcv_num, rcv_buf); memset(snd_buf, 0, 256); strcpy(snd_buf, "message from client"); printf("sizeof(snd_buf): %d\n", sizeof(snd_buf)); printf("send data to server... ...\n"); for(i = 0; i < 4; i++) { write(connect_fd, snd_buf, sizeof(snd_buf)); } printf("send end!\n"); close(connect_fd); return 0; }
与网络的socket通信的区别,即socket地址有些区别,其他的一样。
sockaddr_in用于网络的socket通信,sockaddr_un用于本机上的进程之间的通信。
相关文章推荐
- epoll实现linux进程通信
- linux进程间通过管道通信实现简单的tftp
- linux 进程通信——C语言实现
- 在 Linux 上实现基于 Socket 的多进程实时通信
- Linux进程通信 有名管道实现守护进程
- linux c之通过管道实现兄弟间进程通信:
- 在 Linux 上实现基于 Socket 的多进程实时通信
- Linux下信号通信实现A进程死循环输出A后被C进程处理输出C
- Linux----进程间通信-管道与两个命名管道实现进程双向通信
- 在Linux中实现内部进程通信
- Linux下共享内存通信实现A进程死循环输出A后被C进程处理输出C
- Linux进程通信---共享内存 代码实现
- Linux进程通信---信号量 代码实现
- LINUX 实现两个进程之间的通信
- linux编程---进程通信中,利用socketpair实现子进程间通信
- linux下Epoll实现简单的C/S通信
- linux下通过共享内存在进程之间实现通信(system V)
- linux 下进程间通过信号进行通信的具体实现过程
- 在 Linux 上实现基于 Socket 的多进程实时通信
- Linux下的有名管道(05)---使用两个管道实现两个进程之间的通信(对讲机模式)