1 #include <stdio.h>
2 #include <sys/socket.h>
3 #include <sys/epoll.h>
4 #include <errno.h>
5 #include <arpa/inet.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <sys/socket.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 void setnonblocking(int sock)
13 {
14 int opts;
15 opts=fcntl(sock,F_GETFL);
16 if(opts<0)
17 {
18 perror("fcntl(sock,GETFL)");
19 exit(10);
20 }
21 opts = opts|O_NONBLOCK;
22 if(fcntl(sock,F_SETFL,opts)<0)
23 {
24 perror("fcntl(sock,SETFL,opts)");
25 exit(11);
26 }
27 }
28
29
30 int max_fd_num = 20000 ;
31 void USGE()
32 {
33 printf("[client] [ ip ] [ port ]");
34 }
35
36 int init(const char* ip, const int port)
37 {
38 int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
39 if (listen_sock < 0)
40 {
41 perror("socket");
42 exit(2);
43 }
44
45 struct sockaddr_in local;
46 local.sin_family = AF_INET;
47 local.sin_port = htons(port);
48 local.sin_addr.s_addr = inet_addr(ip);
49 if (bind(listen_sock, (struct sockaddr*)&local, sizeof(local)))
50 {
51 perror("bind");
52 exit(3);
53 }
54 if (listen(listen_sock, 5) < 0)
55 {
56 perror("listen");
57 exit(4);
58 }
59
60 return listen_sock;
61 }
62
63
64
65 int main(int argc,char* argv[])
66 {
67 if (argc < 3)
68 USGE();
69 int listen_sock = init( argv[1], atoi(argv[2]) );
70
71
72 int epfd = epoll_create(2200);
73 if (epfd < 0)
74 {
75 perror("epoll_create");
76 exit(5);
77 }
78
79 struct epoll_event ev, *events;
80 ev.events = EPOLLIN;
81 ev.data.fd = listen_sock;
82
83 epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &ev);
84
85 struct epoll_event ready_events[64];
86 int timeout = -1;
87
88
89
90 while(1)
91 {
92 char buf[1024];
93 //memset(buf, 0, sizeof(buf));
94 //epoll_wait 到的文件描述符个数;
95 int num = epoll_wait(epfd, ready_events, max_fd_num , timeout );
96 int i = 0;
97
98 for( ; i < num ; i++ )
99 {
100 int new_fd = ready_events[i].data.fd;
101 if( new_fd == listen_sock ) //新连接
102 {
103 struct sockaddr_in client;
104 socklen_t len = sizeof(client);
105 int new_fd = accept( listen_sock,(struct sockaddr*)&client ,&len);
106
107 if(new_fd < 0)
108 {
109 perror("accept");
110 continue;
111 }
112 printf("get a new connect: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
113 //把新连接也加入监听队列
114 setnonblocking(new_fd);//将新连接置于非阻塞模式
115 ev.events = EPOLLIN|EPOLLET;
116 ev.data.fd = new_fd;
117 epoll_ctl(epfd,EPOLL_CTL_ADD, new_fd ,&ev);
118 printf("xxxxxxxx 1\n");
119 }
120 else if(ready_events[i].events & EPOLLIN )//发来数据的连接
121 {
122 printf("xxxxxxxx 2\n");
123 ssize_t len = read(new_fd, buf ,sizeof(buf)-1);
124 if( len < 0)
125 {
126 perror("read failed");
127 continue;
128 }
129 else if(len == 0)
130 {
131 printf("Connect closed ");
132 epoll_ctl(epfd, EPOLL_CTL_DEL, new_fd, NULL); //不再监视这个fd;
133 close(new_fd);
134 }
135 else
137 buf[len] = 0;
138 printf("client# %s\n", buf);
139
140 ev.events = EPOLLOUT | EPOLLET;
141 ev.data.fd = new_fd;
142 epoll_ctl(epfd, EPOLL_CTL_MOD, new_fd, &ev);
143 }
144
145 }
146 else if (ready_events[i].events & EPOLLOUT)
147 {
148 write(new_fd, buf, strlen(buf));
149
150 ev.events = EPOLLIN | EPOLLET;
151 ev.data.fd = new_fd;
152 epoll_ctl(epfd, EPOLL_CTL_MOD, new_fd, &ev);
153 printf("xxxxxxxx 3\n");
154 }
155 }
156
157 }
158
159 return 0;
160 }
epoll服务器套路代码
最新推荐文章于 2024-01-02 12:20:28 发布