- 论坛徽章:
- 3
|
回复 4# 耗资喜欢猫
大家帮分析下,主体代码如下:
- void *network_proc_thread(void *arg)
- {
- int listenfd, connfd, sockfd, epfd, nfds, i;
- struct sockaddr_in addr, clientaddr;
- socklen_t clilen = sizeof(struct sockaddr);
- if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
- log_it("sock create failed!: %s\n", strerror(errno));
- pthread_exit(-1);
- }
- int listen_port = LISTEN_PORT;
- bzero(&addr, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(listen_port);
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- //重用端口
- int opt = 1;
- if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) {
- log_it("setsockopt REUSEADDR error: %s\n", strerror(errno));
- }
- if (bind(listenfd, (struct sockaddr*)&addr, sizeof(addr))) {
- log_it("sock bind Failed: %s\n", strerror(errno));
- pthread_exit(-1);
- }
- if (listen(listenfd, 10)) {
- close(listenfd);
- log_it("sock listen Failed!\n");
- pthread_exit(-1);
- }
- log_it("network listening on port: %d ......\n", listen_port);
- //把socket设置为非阻塞方式
- set_nonblock(listenfd);
- //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
- struct epoll_event ev, events[20];
- //生成用于处理accept的epoll专用的文件描述符
- epfd = epoll_create(256);
- ev.data.fd = listenfd;
- ev.events = EPOLLIN | EPOLLET;
- if (epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) {
- perror("epoll_ctl: listenfd");
- exit(1);
- }
- while (1) {
- nfds = epoll_wait(epfd, events, 20, 500);
- for (i = 0; i < nfds; ++i) {
- if(events[i].data.fd == listenfd) {//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。
- connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &clilen);
- if (connfd < 0){
- log_it("accept error!\n");
- continue;
- }
- int port;
- char ip_addr[20] = {0};
- get_ip_port(connfd, ip_addr, &port);
- log_it("receive a connection from: %s : %d, fd: %d ......\n", ip_addr, port, connfd);
- ev.events = EPOLLIN | EPOLLET;
- ev.data.fd = connfd;
- epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
- } else if(events[i].events & EPOLLIN) {
- if ((sockfd = events[i].data.fd) < 0)
- continue;
- request_head_t pkt_head;
- int n;
- if ((n = read(sockfd, &pkt_head, sizeof(pkt_head))) < 0) {
- if (errno == ECONNRESET) {
- log_it("peer may crash!!\n");
- close(sockfd);
- epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL);
- continue;
- } else
- log_it("read request_head_t error: %d\n", errno);
- } else if (n == 0) {
- log_it("peer may close the socket!\n");
- close(sockfd);
- epoll_ctl(epfd, EPOLL_CTL_DEL, sockfd, NULL);
- continue;
- }
-
- ...... //处理请求
-
- ev.data.fd = sockfd;
- ev.events = EPOLLOUT | EPOLLET;
- epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
- } else if(events[i].events & EPOLLOUT) {
- sockfd = events[i].data.fd;
- ev.data.fd = sockfd;
- ev.events = EPOLLIN | EPOLLET;
- epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
- } else if (events[i].events & EPOLLERR) {
- log_it("fd: %d is bad!\n", events[i].data.fd);
- close(events[i].data.fd);
- epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
- } else if (events[i].events & EPOLLHUP) {
- log_it("fd : %d EPOLLHUP!\n", events[i].data.fd);
- }
- }
- }
- log_it("network thread exit normally!\n");
- return 0;
- }
复制代码 带有时间的抓包截图:
|
|