-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab3_server.cc
More file actions
136 lines (118 loc) · 3.05 KB
/
lab3_server.cc
File metadata and controls
136 lines (118 loc) · 3.05 KB
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
// server.cc -- a simple socket server - serves only a single client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAXDATASIZE 1000
#define BACKLOG 10
int main(int argc, char *argv[]) {
int sockfd;
int newfd;
struct addrinfo hints, *servinfo;
struct sockaddr_storage their_addr;
socklen_t sin_size;
char s[INET_ADDRSTRLEN];
int rv;
// lab3
fd_set master;
fd_set read_fds;
int fdmax;
int count = 0;
char buf[MAXDATASIZE];
int numbytes;
if (argc != 2){
printf("usage: server portnum\n");
exit(1);
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, argv[1], &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
if ((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) {
perror("server: socket");
exit(1);
}
if (bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1){
close(sockfd);
perror("server: bind");
exit(1);
}
freeaddrinfo(servinfo);
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
printf("server: waiting for connections on port %s...\n", argv[1]);
/* ---------------------lab3---------------------- */
FD_ZERO(&master);
FD_SET(sockfd, &master);
fdmax = sockfd;
while(1) {
read_fds = master;
if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1){
perror("select");
exit(1);
}
for (int i = 0; i <= fdmax; i++){
if (FD_ISSET(i, &read_fds)){
if (i == sockfd) { // sockfd로부터 메세지 온 경우
sin_size = sizeof their_addr;
// blocking
newfd = accept(sockfd, (struct sockaddr*)&their_addr, &sin_size);
if (newfd == -1) {
perror("accept");
exit(1);
}
else {
FD_SET(newfd, &master);
if(newfd > fdmax)
fdmax = newfd;
}
inet_ntop(their_addr.ss_family, &((struct sockaddr_in*)&their_addr)->sin_addr, s, sizeof s);
printf("server: got connection form %s\n", s);
}
else { // client와 통신하고 있는 socket으로부터 메세지 온 경우
if ((numbytes = recv(i, buf, sizeof buf, 0)) <= 0){
if (numbytes == 0){
printf("selectserver: socket %d hung up\n", i);
}
else {
perror("recv");
}
close(i);
FD_CLR(i, &master);
}
else { // 메세지 온 경우
buf[numbytes] = '\0';
count = 0;
if (strcmp(buf, "user\n")){
for (int i = 0; i <= fdmax; i++){
if (FD_ISSET(i, &master)) count++;
}
char user_buf[MAXDATASIZE];
sprintf(user_buf, "number of online user: %d\n", count - 1);
memset(buf, '\0', sizeof buf);
strcpy(buf, user_buf);
}
else {
printf("server received: %s\n", buf);
}
if (send(i, buf, strlen(buf), 0) == -1)
perror("send");
}
}
}
}
}
return 0;
}