-
Notifications
You must be signed in to change notification settings - Fork 7
/
server.c
170 lines (147 loc) · 6.16 KB
/
server.c
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define MSG_SIZE 80
#define MAX_CLIENTS 150
#define MYPORT 7400
void exitClient(int fd, fd_set *readfds, char fd_array[], int *num_clients)
{
int i;
close(fd);
FD_CLR(fd, readfds); /*clear the leaving client from the set*/
for (i = 0; i < (*num_clients) - 1; i++)
if (fd_array[i] == fd)
break;
for (; i < (*num_clients) - 1; i++)
(fd_array[i]) = (fd_array[i + 1]);
(*num_clients)--;
}
int main(int argc, char *argv[])
{
int i=0;
int count=0;
char pass[1];
int port,result;
int num_clients = 0;
int server_sockfd, client_sockfd;
struct sockaddr_in server_address;
int addresslen = sizeof(struct sockaddr_in);
int fd;
char fd_array[MAX_CLIENTS];
fd_set readfds, testfds, clientfds;
char msg[MSG_SIZE + 1];
char kb_msg[MSG_SIZE + 10];
/*Server*/
if(argc==1 || argc == 3){
if(argc==3){
if(!strcmp("-p",argv[1])){
sscanf(argv[2],"%i",&port);
}
else{
printf("Invalid parameter.\nUsage: chat [-p PORT] HOSTNAME\n");
exit(0);
}
}
else
port=MYPORT;
printf("\n\t******************** iBOT Server ********************\n");
printf("\n\n\t Authentication :\n\n\t Password : ");
scanf("%s",&pass);
if(strcmp(pass,"cyber")!=0){
printf("\n\n !! failure !!\n\n " );
exit(0);
}
printf("\n*** Server waiting (enter \"quit\" to stop): \n");
fflush(stdout);
/* Create and name a socket for the server */
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(port);
bind(server_sockfd, (struct sockaddr *)&server_address, addresslen);
/* Create a connection queue and initialize a file descriptor set */
listen(server_sockfd, 1);
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
FD_SET(0, &readfds); /* Add keyboard to file descriptor set */
/* Now wait for clients and requests */
while (1){
testfds = readfds;
select(FD_SETSIZE, &testfds, NULL, NULL, NULL);
/* If there is activity, find which descriptor it's on using FD_ISSET */
for (fd = 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd, &testfds)) {
if (fd == server_sockfd) { /* Accept a new connection request */
client_sockfd = accept(server_sockfd, NULL, NULL);
if (num_clients < MAX_CLIENTS) {
FD_SET(client_sockfd, &readfds);
fd_array[num_clients]=client_sockfd;
/*Client ID*/
printf("\n -> Bot No. %d standby for orders\n",++num_clients);
printf("\n >> ");
fflush(stdout);
send(client_sockfd,msg,strlen(msg),0);
}
else{
sprintf(msg, "XSorry, too many clients. Try again later.\n");
write(client_sockfd, msg, strlen(msg));
close(client_sockfd);
}
}
else
if (fd == 0){
printf(" >> "); /* Process keyboard activity */
fgets(kb_msg, MSG_SIZE + 1, stdin);
if (strcmp(kb_msg, "quit\n")==0) {
sprintf(msg, "iBot Server is shutting down.\n");
for (i = 0; i < num_clients ; i++) {
write(fd_array[i], msg, strlen(msg));
close(fd_array[i]);
}
close(server_sockfd);
exit(0);
}
else{
sprintf(msg, "M%s", kb_msg);
for (i = 0; i < num_clients ; i++)
write(fd_array[i], msg, strlen(msg));
}
}
else
if(fd){
result = read(fd, msg, MSG_SIZE); /*read data from open socket*/
if(result==-1)
perror("read()");
else
if(result>0){
sprintf(kb_msg,"MClient CID %2d",fd); /*read 2 bytes client id*/
msg[result]='\0';
/*concatinate the client id with the client's message*/
strcat(kb_msg," ");
strcat(kb_msg,msg+1);
/*print to other clients*/
for(i=0;i<num_clients;i++){
if (fd_array[i] != fd) /*dont write msg to same client*/
write(fd_array[i],kb_msg,strlen(kb_msg));
}
/*print to server */
printf("%s",kb_msg+1);
/*Exit Client*/
if(msg[0] == 'X'){
exitClient(fd,&readfds, fd_array,&num_clients);
}
}
}
else{
exitClient(fd,&readfds, fd_array,&num_clients); /* A client is leaving */
}
}
}
}
}
}