-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcpserver.cpp
151 lines (134 loc) · 4.19 KB
/
tcpserver.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
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// Created by Administrator on 2017/2/24.
//
#include "unp.h"
using namespace std;
void str_echo(int sockfd){
ssize_t n;
char buf[MAX_BUFF_SIZE] = {0};
again:
while((n = read(sockfd,buf,MAX_BUFF_SIZE)) > 0){
Writen(sockfd,buf,n);
}
if(n < 0 && errno == EINTR)
goto again;
else if(n < 0)
err_sys("str_echo:read echo");
}
#if 0
int main(int argc,char **argv){
int listenfd,connfd;
pid_t childpid;
socklen_t clilen;
listenfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
assert(listenfd > 2);
struct sockaddr_in cliaddr,servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//inet_pton(AF_INET,INADDR_ANY,&servaddr.sin_addr);//这儿不能这么写
int ret = bind(listenfd,(struct sockaddr*)&servaddr, sizeof(servaddr));
assert(ret !=-1);
ret = listen(listenfd,5);
assert(ret != -1);
Signal(SIGCHLD,sig_chld);
for(;;){
clilen = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
if(connfd < 0){
if(errno == EINTR)continue;
else err_sys("accept error");
}
if((childpid = fork()) == 0){
close(listenfd);
str_echo(connfd);
close(connfd);
exit(0);
}
close(connfd);
}
return 0;
}
#else
int main(int argc,char **argv){
int listenfd,connfd,sockfd;
int maxfd,maxi,i;
int nReady,client[FD_SETSIZE];
socklen_t clilen;
fd_set rset,allset;
ssize_t n;
char buf[MAX_BUFF_SIZE] = {0};
listenfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
assert(listenfd > 2);
struct sockaddr_in cliaddr,servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//inet_pton(AF_INET,INADDR_ANY,&servaddr.sin_addr);//这儿不能这么写
int ret = bind(listenfd,(struct sockaddr*)&servaddr, sizeof(servaddr));
assert(ret !=-1);
ret = listen(listenfd,5);
assert(ret != -1);
maxfd = listenfd;
maxi = -1;
for(int i = 0 ;i < FD_SETSIZE;++i)
client[i] = -1;
FD_ZERO(&allset);
FD_SET(listenfd,&allset);
signal(SIGHUP, SIG_IGN);
for(;;){
rset = allset;
nReady = select(maxfd+1,&rset,NULL,NULL,NULL);
if(nReady == 0)continue;
else if(nReady < 0 )err_sys("select error");
else
{
if(FD_ISSET(listenfd,&rset)){
clilen = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen);
if(connfd < 0){
if(errno == EINTR)continue;
else err_sys("accept error");
}
for (i = 0; i < FD_SETSIZE; ++i) {
if(client[i] < 0){
client[i] = connfd;
break;
}
}
if (i == FD_SETSIZE){
err_quit("too much connect");
}
FD_SET(connfd,&allset);
if(connfd > maxfd)
maxfd = connfd;
if(i > maxi)
maxi = i;
if(--nReady <= 0)continue;
}
for (int j = 0; j <= maxi; ++j) {
if((sockfd = client[j]) < 0)continue;
if(FD_ISSET(sockfd,&rset)){
if((n = read(sockfd,buf,MAX_BUFF_SIZE)) == 0){
close(sockfd);
FD_CLR(sockfd,&allset);
client[i] = -1;
}
else{
Writen(sockfd,buf,n);
}
if(--nReady <= 0)break;
}
}
}
}
close(listenfd);
for (i = 0; i < FD_SETSIZE; ++i) {
if(client[i] < 0)continue;
close(client[i]);
}
return 0;
}
#endif