然后基本的socket编程,用TCP做两个进程互相发消息。C端主动发hello,S端收到后回world。

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/socket.h> 5 #include <netinet/in.h> 6 #include <arpa/inet.h> 7 #include <string.h> 8 9 #define MAXLINE 80 10 #define SERV_PORT 8000 11 12 int main() 13 { 14 char buf[MAXLINE]; 15 int listenfd = 0; 16 17 listenfd = socket(AF_INET, SOCK_STREAM, 0); 18 19 struct sockaddr_in servaddr = {0}; 20 servaddr.sin_family = AF_INET; 21 servaddr.sin_port = htons(SERV_PORT); 22 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 23 24 bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); 25 listen(listenfd, 20); 26 27 printf("Accepting connections ... "); 28 while(1) { 29 struct sockaddr_in cliaddr = {0}; 30 socklen_t cliaddr_len = sizeof(cliaddr); 31 int connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); 32 33 char str[INET_ADDRSTRLEN]; 34 printf("connect from %s at PORT %d ", 35 inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), 36 ntohs(cliaddr.sin_port)); 37 while(1) { 38 int count = read(connfd, buf, MAXLINE); 39 if(count == 0) 40 break; 41 42 if(!strcmp(buf, "Hello")) { 43 printf("client send %s ", buf); 44 write(connfd, "World", 6); 45 } 46 } 47 close(connfd); 48 printf("closed from %s at PORT %d ", 49 inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), 50 ntohs(cliaddr.sin_port)); 51 } 52 return 0; 53 }
c端

1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 8 #define MAXLINE 80 9 #define SERV_PORT 8000 10 #define MESSAGE "Hello" 11 12 int main(int argc, char *argv[]) 13 { 14 char buf[MAXLINE]; 15 16 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 17 18 struct sockaddr_in servaddr = {0}; 19 servaddr.sin_family = AF_INET; 20 inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr); 21 servaddr.sin_port = htons(SERV_PORT); 22 23 if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) 24 { 25 printf("connected failed"); 26 return 1; 27 } 28 29 write(sockfd, MESSAGE, sizeof(MESSAGE)); 30 int count = read(sockfd, buf, MAXLINE); 31 32 printf("Response from server: %s ", buf); 33 34 close(sockfd); 35 return 0; 36 }
然后把S端用EPOLL做成异步处理,可以同时给好几个C端回复。

1 #include <iostream> 2 #include <sys/socket.h> 3 #include <sys/epoll.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <fcntl.h> 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <errno.h> 10 #include <stdlib.h> 11 #include <strings.h> 12 #include <string.h> 13 14 using namespace std; 15 16 #define MAXLINE 5 17 #define OPEN_MAX 100 18 #define LISTENQ 20 19 #define SERV_PORT 8000 20 #define INFTIM 1000 21 22 int main(void) 23 { 24 int i, maxi, listenfd, connfd, sockfd, epfd, nfds; 25 ssize_t n; 26 char line[MAXLINE]; 27 char buf[20]; 28 socklen_t clilen; 29 30 struct epoll_event ev, events[20]; 31 epfd = epoll_create(256); 32 struct sockaddr_in clientaddr; 33 struct sockaddr_in serveraddr; 34 listenfd = socket(AF_INET, SOCK_STREAM, 0); 35 36 ev.data.fd = listenfd; 37 ev.events = EPOLLIN | EPOLLET; 38 epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); 39 40 bzero(&serveraddr, sizeof(serveraddr)); 41 serveraddr.sin_family = AF_INET; 42 serveraddr.sin_port = htons(SERV_PORT); 43 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 44 45 bind(listenfd, (sockaddr *)&serveraddr, sizeof(serveraddr)); 46 listen(listenfd, LISTENQ); 47 48 for( ; ; ) { 49 nfds = epoll_wait(epfd, events, 20, 500); 50 51 for(i=0;i<nfds;i++) { 52 if(events[i].data.fd == listenfd) { 53 clilen = sizeof(clientaddr); 54 connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen); 55 ev.data.fd = connfd; 56 ev.events = EPOLLIN | EPOLLET; 57 epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev); 58 } else if(events[i].events & EPOLLIN) { 59 if((sockfd = events[i].data.fd) < 0) { 60 continue; 61 } 62 if((n = read(sockfd, line, MAXLINE)) < 0) { 63 if(errno == ECONNRESET) { 64 close(sockfd); 65 events[i].data.fd = -1; 66 } else { 67 std::cout<<"readline error"<<std::endl; 68 } 69 } else if(n == 0) { 70 close(sockfd); 71 events[i].data.fd = -1; 72 } 73 ev.data.fd = sockfd; 74 ev.events = EPOLLOUT | EPOLLET; 75 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 76 } else if(events[i].events & EPOLLOUT) { 77 sockfd = events[i].data.fd; 78 if(!strcmp(line, "Hello")) { 79 strcpy(buf, "World"); 80 write(sockfd, buf, 6); 81 } 82 ev.data.fd = sockfd; 83 ev.events = EPOLLIN | EPOLLET; 84 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 85 } 86 } 87 } 88 }
c端

1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 8 #define MAXLINE 80 9 #define SERV_PORT 8000 10 #define MESSAGE "Hello" 11 12 int main(int argc, char *argv[]) 13 { 14 char buf[MAXLINE]; 15 16 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 17 18 struct sockaddr_in servaddr = {0}; 19 servaddr.sin_family = AF_INET; 20 inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr); 21 servaddr.sin_port = htons(SERV_PORT); 22 23 if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { 24 printf("connected failed"); 25 return 1; 26 } 27 28 for( ; ;) { 29 write(sockfd, MESSAGE, sizeof(MESSAGE)); 30 int count = read(sockfd, buf, MAXLINE); 31 32 printf("Response from server: %s ", buf); 33 sleep(1); 34 } 35 close(sockfd); 36 return 0; 37 }
4,然后把S做成多进程,任何一个进程收到任何一个C端的消息后,广播给其他进程,然后所有进程打印如下信息:“几号”进程收到“几号”客户端的“啥啥”消息(由“几号”进程转发)。不是转发的,括号内省略。“”内的替换为正确值。
S端:

1 #ifndef _3PROCESS_FD_H_ 2 #define _3PROCESS_FD_H_ 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <iostream> 8 9 using namespace std; 10 11 #include <sys/socket.h> 12 #include <unistd.h> 13 #include <sys/wait.h> 14 #include <fcntl.h> 15 #include <sys/uio.h> 16 #include <sys/epoll.h> 17 #include <sys/types.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 #include <arpa/inet.h> 21 #include <strings.h> 22 #include <errno.h> 23 #include "3process_fun.h" 24 25 typedef struct { 26 int index; 27 int chanel[2]; 28 }process_t; 29 30 #define MAXPROCESS 3 31 #define MAXLINE 100 32 33 #define SERV_PORT 9876 34 35 #endif

1 #include "3process_fd.h" 2 3 void setnonblocking(int sock) 4 { 5 int opts; 6 opts = fcntl(sock, F_GETFL); 7 if(opts < 0) { 8 cout<<"fcntl error"<<endl; 9 exit(1); 10 } 11 12 opts = opts | O_NONBLOCK; 13 if(fcntl(sock, F_SETFL, opts) < 0) { 14 cout<<"set nonblock error"<<endl; 15 exit(1); 16 } 17 } 18 19 void child_process(int index, process_t *processes) 20 { 21 cout<<"child "<<index<<" pid: "<<getpid()<<endl; 22 struct epoll_event ev, events[20]; 23 int epfd, nfds, sockfd, listenfd, connfd; 24 int i, n; 25 char buf[MAXLINE], line[MAXLINE]; 26 struct sockaddr_in servaddr; 27 struct sockaddr_in clientaddr; 28 socklen_t clilen = sizeof(struct sockaddr_in); 29 30 /* socket bind and listen */ 31 listenfd = socket(AF_INET, SOCK_STREAM, 0); 32 setnonblocking(listenfd); 33 bzero(&servaddr, sizeof(servaddr)); 34 servaddr.sin_family = AF_INET; 35 servaddr.sin_port = htons(SERV_PORT); 36 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 37 bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); 38 listen(listenfd, 20); 39 40 /* create epoll */ 41 epfd = epoll_create(256); 42 ev.data.fd = (processes+index)->chanel[1]; 43 ev.events = EPOLLIN | EPOLLET; 44 epoll_ctl(epfd, EPOLL_CTL_ADD, (processes+index)->chanel[1], &ev); 45 46 ev.data.fd = listenfd; 47 ev.events = EPOLLIN | EPOLLET; 48 epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev); 49 50 for( ; ;) { 51 nfds = epoll_wait(epfd, events, 100, 500); 52 for(i=0;i<nfds;i++) { 53 if(events[i].data.fd == listenfd) { 54 connfd = accept(listenfd, (sockaddr *)&clientaddr, &clilen); 55 if(connfd < 0) { 56 cout<<"[child"<<index<<"] accept error"<<endl; 57 exit(1); 58 } 59 setnonblocking(connfd); 60 char *str = inet_ntoa(clientaddr.sin_addr); 61 cout<<"[child"<<index<<"] connect from "<<str<<endl; 62 ev.data.fd = connfd; 63 ev.events = EPOLLIN | EPOLLET; 64 epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev); 65 } else if(events[i].data.fd == (processes+index)->chanel[1]) { 66 read((processes+index)->chanel[1], buf, sizeof(buf)); 67 cout<<"child "<<index<<" recv: "<<buf<<endl; 68 } else if(events[i].events & EPOLLIN) { 69 if((sockfd = events[i].data.fd) < 0) { 70 ev.data.fd = sockfd; 71 ev.events = EPOLLIN | EPOLLET; 72 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev); 73 continue; 74 } 75 if((n = read(sockfd, line, MAXLINE)) < 0) { 76 if(errno == ECONNRESET) { 77 close(sockfd); 78 events[i].data.fd = -1; 79 ev.data.fd = sockfd; 80 ev.events = EPOLLIN | EPOLLET; 81 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev); 82 } else { 83 cout<<"readline error"<<endl; 84 } 85 } else if(n == 0) { 86 close(sockfd); 87 events[i].data.fd = -1; 88 ev.data.fd = sockfd; 89 ev.events = EPOLLIN | EPOLLET; 90 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev); 91 cout<<"[child"<<index<<"] close socket?"<<endl; 92 continue; 93 } 94 cout<<"[child"<<index<<"] here is a EPOLLIN event."<<endl; 95 ev.data.fd = sockfd; 96 ev.events = EPOLLOUT | EPOLLET; 97 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 98 } else if(events[i].events & EPOLLOUT) { 99 if((sockfd = events[i].data.fd) < 0) { 100 ev.data.fd = sockfd; 101 ev.events = EPOLLIN | EPOLLET; 102 epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, &ev); 103 continue; 104 } 105 if(!strcmp(line, "Hello")) { 106 strcpy(buf, "World"); 107 write(sockfd, buf, strlen(buf)); 108 } 109 cout<<"[child"<<index<<"] here is a EPOLLOUT event."<<endl; 110 ev.data.fd = sockfd; 111 ev.events = EPOLLIN | EPOLLET; 112 epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev); 113 } 114 } 115 } 116 117 exit(0); 118 } 119 120 int main(int argc, char *argv[]) 121 { 122 cout<<"current pid: "<<getpid()<<endl; 123 process_t *pprocess = (process_t *)malloc(sizeof(process_t)*MAXPROCESS); 124 int i; 125 int pid[MAXPROCESS]; 126 127 for(i=0;i<MAXPROCESS;i++) { 128 (pprocess+i)->index = i; 129 if(socketpair(AF_UNIX, SOCK_STREAM, 0, (pprocess+i)->chanel) == -1) { 130 cout<<"failed to create domain socket by socketpair"<<endl; 131 exit(1); 132 } 133 } 134 135 for(i=0;i<MAXPROCESS;i++) { 136 pid[i] = fork(); 137 switch(pid[i]) { 138 case -1: 139 cout<<"fork error"<<endl; 140 exit(-1); 141 case 0: 142 child_process(i, pprocess); 143 exit(1); 144 defualt: 145 cout<<"default?"<<endl; 146 break; 147 } 148 } 149 150 for(i=0;i<MAXPROCESS;i++) { 151 write((pprocess+i)->chanel[0], "Hello child", strlen("Hello child")); 152 } 153 154 for(;;) { 155 pause(); 156 } 157 }
C端:

1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 #include <errno.h> 8 9 #define MAXLINE 80 10 #define SERV_PORT 9876 11 #define MESSAGE "Hello" 12 13 int main(int argc, char *argv[]) 14 { 15 char buf[MAXLINE]; 16 17 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 18 19 struct sockaddr_in servaddr = {0}; 20 servaddr.sin_family = AF_INET; 21 inet_pton(AF_INET, "192.168.1.63", &servaddr.sin_addr); 22 servaddr.sin_port = htons(SERV_PORT); 23 24 if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) 25 { 26 printf("connected failed:%d,%s",errno, strerror(errno)); 27 return 1; 28 } 29 while(1) 30 { 31 write(sockfd, MESSAGE, sizeof(MESSAGE)); 32 // int count = read(sockfd, buf, MAXLINE); 33 34 // printf("Response from server: %s ", buf); 35 sleep(6); 36 } 37 38 close(sockfd); 39 return 0; 40 }