-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathserver.cpp
138 lines (135 loc) · 2.73 KB
/
server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<strings.h>
#include<errno.h>
#include<poll.h>
#define IPADDRESS "127.0.0.1"
#define PORT 6666
#define MAXLINE 1024
#define LISTENQ 5
#define OPEN_MAX 1000
#define INFTIM -1
int bind_and_listen()
{
int serverfd;
struct sockaddr_in my_addr;
unsigned int sin_size;
if((serverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
return -1;
}
printf("socket ok\n");
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 0);
if(bind(serverfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
return -2;
}
printf("bind ok\n");
if(listen(serverfd, LISTENQ) == -1)
{
perror("listen");
return -3;
}
printf("listen ok\n");
return serverfd;
}
void do_poll(int listenfd)
{
int connfd, sockfd;
struct sockaddr_in cliaddr;
socklen_t cliaddrlen;
struct pollfd clientfds[OPEN_MAX]; //可接受的client最大值
int maxi;
int i;
int nready;
clientfds[0].fd = listenfd;
clientfds[0].events = POLLIN;
for(i = 1; i<OPEN_MAX; i++)
clientfds[i].fd = -1;
maxi = 0;
//初始化工作完成
while(1)
{
nready = poll(clientfds, maxi+1, INFTIM);
if(nready == -1)
{
perror("poll error:");
exit(1);
}
if(clientfds[0].revents & POLLIN)
{
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen)) == -1)
{
if(errno == EINTR)
continue;
else
{
perror("accept error:");
exit(1);
}
}
fprintf(stdout, "accept a new client:%s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);
for(i = 1; i<OPEN_MAX; i++)
{
if(clientfds[i].fd<0)
{
clientfds[i].fd = connfd;
break;
}
}
if(i == OPEN_MAX)
{
fprintf(stderr, "too many clients.\n");
exit(1);
}
clientfds[i].events = POLLIN;
maxi = (i>maxi?i:maxi);
if(--nready<=0) //当前准备好的只有serverfd
continue;
}
char buf[MAXLINE];
memset(buf, 0, MAXLINE);
int readlen = 0;
for(i = 1; i<maxi; i++) //第0个是监听端口
{
if(clientfds[i].fd<0)
continue;
if(clientfds[i].revents & POLLIN)
{
readlen = read(clientfds[i].fd, buf, MAXLINE);
if(readlen == 0)
{
close(clientfds[i].fd);
clientfds[i].fd = -1;
continue;
}
printf("msg is:");
write(STDOUT_FILENO, buf, readlen);
write(clientfds[i].fd, buf, readlen); //发回去
}
}
}
}
int main(int argc, char* argv[])
{
int listenfd = bind_and_listen();
if(listenfd<0)
{
return 0;
}
do_poll(listenfd);
return 0;
}