分析見下回分解socket
server.cpp函數
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/epoll.h> #include <unistd.h> #include <sys/types.h> #define IPADDRESS "127.0.0.1" #define PORT 6666 #define MAXSIZE 1024 #define LISTENQ 5 #define FDSIZE 1000 #define EPOLLEVENTS 100 // 建立套接字並進行綁定 int socket_bind(const char* ip, int port); // IO多路複用 epoll void do_epoll(int listenfd); // 處理事件函數 void handle_events(int epollfd, struct epoll_event *events, int num, int listenfd, char* buf); // 處理接收到的鏈接 void handle_accept(int epollfd, int listenfd); // 讀處理 void do_read(int epollfd, int fd, char* buf); // 寫處理 void do_write(int epollfd, int fd, char *buf); // 添加事件 void add_event(int epollfd, int fd, int state); // 修改事件 void modify_event(int epollfd, int fd, int state); // 刪除事件 void delete_event(int epollfd, int fd, int state); int main(int argc, char *argv[]) { int listenfd = 0; listenfd = socket_bind(IPADDRESS, PORT); listen(listenfd, LISTENQ); do_epoll(listenfd); return 0; } int socket_bind(const char* ip, int port) { int listenfd = 0; struct sockaddr_in servaddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd == -1) { perror("socket error"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; inet_pton(AF_INET, ip, &servaddr.sin_addr); servaddr.sin_port = htons(port); if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { perror("bind error: "); exit(1); } return listenfd; } void do_epoll(int listenfd) { int epollfd; struct epoll_event events[EPOLLEVENTS]; int ret; char buf[MAXSIZE]; memset(buf, 0, MAXSIZE); // 建立一個描述符 epollfd = epoll_create(FDSIZE); // 添加監聽描述事件 add_event(epollfd, listenfd, EPOLLIN); while(true) { // 獲取已經準備好的描述事件 ret = epoll_wait(epollfd, events, EPOLLEVENTS, -1); handle_events(epollfd, events, ret, listenfd, buf); } close(epollfd); } void handle_events(int epollfd, struct epoll_event *events, int num, int listenfd, char* buf) { for(int i = 0; i < num; i++ ) { int fd = events[i].data.fd; // 根據描述符的類型和事件類型進行處理 if((fd == listenfd) && (events[i].events & EPOLLIN)) { handle_accept(epollfd, listenfd); } else if(events[i].events & EPOLLIN) { do_read(epollfd, fd, buf); } else if(events[i].events & EPOLLOUT) { do_write(epollfd, fd, buf); } } } void handle_accept(int epollfd, int listenfd) { int clifd; struct sockaddr_in cliaddr; socklen_t cliaddrlen; clifd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen); if(clifd == -1) { perror("accpet error:"); } else { printf("accept a new client: %s : %d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); // 添加一個客戶端描述符和事件 add_event(epollfd, clifd, EPOLLIN); } } void do_read(int epollfd, int fd, char* buf) { int nread = read(fd, buf, MAXSIZE); if(nread == -1) { perror("read error:"); close(fd); delete_event(epollfd, fd, EPOLLIN); } else if(nread == 0) { fprintf(stderr, "client close.\n"); close(fd); delete_event(epollfd, fd, EPOLLIN); } else { printf("read message is: %s \n", buf); modify_event(epollfd, fd, EPOLLOUT); } } void do_write(int epollfd, int fd, char* buf) { int nwrite = write(fd, buf, strlen(buf)); if(nwrite == -1) { perror("write error: "); close(fd); delete_event(epollfd, fd, EPOLLOUT); } else { modify_event(epollfd, fd, EPOLLIN); } memset(buf, 0, MAXSIZE); } void add_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); } void delete_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev); } void modify_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev); }
client.cppcode
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/epoll.h> #include <unistd.h> #include <sys/types.h> #define IPADDRESS "127.0.0.1" #define SERV_PORT 6666 #define MAXSIZE 1024 #define FDSIZE 1024 #define EPOLLEVENTS 20 int count = 0; void handle_connection(int sockfd); // 處理事件函數 void handle_events(int epollfd, struct epoll_event *events, int num, int sockfd, char* buf); // 讀處理 void do_read(int epollfd, int fd, int sockfd, char* buf); // 寫處理 void do_write(int epollfd, int fd, int sockfd, char* buf); // 添加事件 void add_event(int epollfd, int fd, int state); // 修改事件 void modify_event(int epollfd, int fd, int state); // 刪除事件 void delete_event(int epollfd, int fd, int state); int main(int argc, char *argv[]) { int sockfd; struct sockaddr_in servaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); inet_pton(AF_INET, IPADDRESS, &servaddr.sin_addr); connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); //處理鏈接 handle_connection(sockfd); close(sockfd); return 0; } void handle_connection(int sockfd) { int epollfd; struct epoll_event events[EPOLLEVENTS]; char buf[MAXSIZE]; int ret; epollfd = epoll_create(FDSIZE); add_event(epollfd, STDIN_FILENO, EPOLLIN); while(1) { ret = epoll_wait(epollfd, events, EPOLLEVENTS, -1); handle_events(epollfd, events, ret, sockfd, buf); } close(epollfd); } void handle_events(int epollfd, struct epoll_event *events, int num, int sockfd, char* buf) { for(int i = 0; i < num; i++ ) { int fd = events[i].data.fd; // 根據描述符的類型和事件類型進行處理 if(events[i].events & EPOLLIN) { do_read(epollfd, fd, sockfd, buf); } else if(events[i].events & EPOLLOUT) { do_write(epollfd, fd, sockfd, buf); } } } void do_read(int epollfd, int fd, int sockfd, char* buf) { int nread = read(fd, buf, MAXSIZE); if(nread == -1) { perror("read error:"); close(fd); } else if(nread == 0) { fprintf(stderr, "client close.\n"); close(fd); } else { if(fd == STDIN_FILENO) { add_event(epollfd, sockfd, EPOLLOUT); } else { delete_event(epollfd, sockfd, EPOLLIN); add_event(epollfd, STDOUT_FILENO, EPOLLOUT); } } } void do_write(int epollfd, int fd, int sockfd, char* buf) { int nwrite = write(fd, buf, strlen(buf)); char tmp[105] = {0}; snprintf(tmp, sizeof(tmp), "%s_%02d\n", buf, count++); nwrite = write(fd, tmp, strlen(tmp)); if(nwrite == -1) { perror("write error:"); close(fd); } else { if(fd == STDOUT_FILENO) { delete_event(epollfd, fd, EPOLLOUT); } else { modify_event(epollfd, fd, EPOLLIN); } } memset(buf, 0, MAXSIZE); } void add_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); } void delete_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev); } void modify_event(int epollfd, int fd, int state) { struct epoll_event ev; ev.events = state; ev.data.fd = fd; epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev); }