-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.cpp
More file actions
132 lines (124 loc) · 3.28 KB
/
Copy pathserver.cpp
File metadata and controls
132 lines (124 loc) · 3.28 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
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
struct client_info {
int sockno;
char ip[INET_ADDRSTRLEN];
};
int clients[100];
int n = 0;
int cnt=1;
long long binpow(long long a, long long b, long long m) {
a %= m;
long long res = 1;
while (b > 0) {
if (b & 1)
res = res * a % m;
a = a * a % m;
b >>= 1;
}
return res;
}
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void sendtoall(char *msg,int curr)
{
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < n; i++) {
if(clients[i] != curr) {
if(send(clients[i],msg,strlen(msg),0) < 0) {
perror("sending failure");
continue;
}
}
}
pthread_mutex_unlock(&mutex);
}
void *recvmg(void *sock)
{
struct client_info cl = *((struct client_info *)sock);
char msg[500];
int len;
int i;
int j;
while((len = recv(cl.sockno,msg,500,0)) > 0) {
msg[len] = '\0';
sendtoall(msg,cl.sockno);
memset(msg,'\0',sizeof(msg));
}
pthread_mutex_lock(&mutex);
printf("%s disconnected\n",cl.ip);
for(i = 0; i < n; i++) {
if(clients[i] == cl.sockno) {
j = i;
while(j < n-1) {
clients[j] = clients[j+1];
j++;
}
}
}
n--;
pthread_mutex_unlock(&mutex);
}
int main(int argc, char *argv[]) {
struct sockaddr_in my_addr, their_addr;
int my_sock;
int their_sock;
socklen_t their_addr_size;
int portno;
pthread_t sendt, recvt;
char msg[500];
int len;
struct client_info cl;
char ip[INET_ADDRSTRLEN];
if (argc > 2) {
printf("too many arguments");
exit(1);
}
portno = atoi(argv[1]);
my_sock = socket(AF_INET, SOCK_STREAM, 0);
memset(my_addr.sin_zero, '\0', sizeof(my_addr.sin_zero));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(portno);
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
their_addr_size = sizeof(their_addr);
if (bind(my_sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) != 0) {
perror("binding unsuccessful");
exit(1);
}
if (listen(my_sock, 5) != 0) {
perror("listening unsuccessful");
exit(1);
}
while (1) {
if ((their_sock = accept(my_sock, (struct sockaddr *)&their_addr, &their_addr_size)) < 0) {
perror("accept unsuccessful");
exit(1);
}
pthread_mutex_lock(&mutex);
inet_ntop(AF_INET, (struct sockaddr *)&their_addr, ip, INET_ADDRSTRLEN);
printf("%s connected\n", ip);
cl.sockno = their_sock;
strcpy(cl.ip, ip);
clients[n] = their_sock;
n++;
// Send the value of cnt to the newly connected client and switch cnt.
char cnt_msg[10];
snprintf(cnt_msg, sizeof(cnt_msg), "%d", cnt);
if (send(their_sock, cnt_msg, strlen(cnt_msg), 0) < 0) {
perror("sending failure");
// Additional debug information
printf("Failed to send cnt_msg to client. their_sock: %d\n", their_sock);
}
cnt = (cnt == 1) ? 2 : 1;
pthread_create(&recvt, NULL, recvmg, &cl);
pthread_mutex_unlock(&mutex);
}
return 0;
}