-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.c
142 lines (127 loc) · 4.14 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
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <signal.h>
#include "server.h"
#define MAX_CLIENTS 200
#define MAX_MSGSIZE 2000
#define TIC_RATE 500000
/*PLAN: maintain shared 'server state', shared memory
structure that contains all info that, when updated, is rebroadcast to every client.
1.server maintains udp info for every
client connected to game.
2.Select()'s from among the list. reads new state
3. create 'changed state' struct. aggregate changes
over some time period, (1/10 second say) then broadcast to clients all changes in that time period.
*/
int next_fid;
struct client_data srv_state[MAX_CLIENTS];
struct client_data dirty_state[MAX_CLIENTS];
int openfd;
int main(int argc, char* argv[]){
//printf("argc:%d arg1:%s\n", argc, argv[1]);
clr_connections(srv_state);
clr_connections(dirty_state);
int cont =1;
next_fid =0;
struct sigaction act;
act.sa_handler = (update_clients_handler);
if(sigaction(SIGALRM, &act, NULL)){
printf("error setting alarm handler\n");
}
struct timeval tv;
//kill(getpid(), SIGVTALRM);
tv.tv_sec=0;
tv.tv_usec = TIC_RATE;
const struct itimerval it_update = {tv, tv};
if(setitimer(ITIMER_REAL, &it_update, NULL)) perror("setitimer failure");
openfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(HOST_PORT);
bind(openfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in));
while(cont){
struct client_data new_client;
int socklen = sizeof(struct sockaddr_in);
if(recvfrom(openfd, &new_client, sizeof(struct client_data), 0, (struct sockaddr*)&new_client.destaddr, &socklen)!=0){
printf("recieved msg. client_id=%d, address=%s\n", new_client.client_id, inet_ntoa(new_client.destaddr.sin_addr));
if(new_client.client_id>-1){
if(handle_msg(&new_client, dirty_state, openfd)){
printf("error handle_msg()\n");
return -1;
}
}
else{
if(handle_new_client(&new_client, dirty_state, openfd)){
printf("error handle_msg()\n");
return -1;
}
}
}
}
return 0;
}
int handle_msg(struct client_data* msg, struct client_data* ss, int sockfd){
printf("in handle_msg. Got message from client_id=%d\n", msg->client_id);
print_clnt_data(msg);
memcpy(&ss[msg->client_id], msg, sizeof(struct client_data));
return 0;
}
int handle_new_client(struct client_data* msg, struct client_data* ss, int sockfd){
if(next_fid>MAX_CLIENTS){
printf("next client_id(%d > max_clients(%d)\n", next_fid, MAX_CLIENTS);
return -1;
}
printf("recieved new client request. addr=%s\n", inet_ntoa(msg->destaddr.sin_addr));
msg->client_id = next_fid;
memcpy(&ss[next_fid], msg, sizeof(struct client_data));
printf("assigned client id=%d ", ss[next_fid].client_id);
next_fid = find_free_slot(ss);
printf("and set next_fid=%d\n", next_fid);
return 0;
}
static void update_clients_handler(int signum){
printf("updating clients\n");
int i;
for(i=0; i<MAX_CLIENTS; i++){
if(dirty_state[i].client_id!=-1){
printf("updating client(i=%d) client_id=%d\n", i, dirty_state[i].client_id);
sendto(openfd, dirty_state, 200*sizeof(struct client_data), 0, (struct sockaddr*)&dirty_state[i].destaddr, sizeof(struct sockaddr_in));
}
}
printf("done updating clients\n");
}
int find_free_slot(struct client_data* ss){
int i;
for(i=0; i<MAX_CLIENTS; i++){
if(ss[i].client_id==-1){
next_fid = i;
return next_fid;
}
}
printf("error no more clients allowed\n");
return -1;
}
void clr_connections(struct client_data* ss){
int i;
//memset(ss, '0', 200*sizeof(struct client_data));
for(i=0; i<MAX_CLIENTS; i++){
ss[i].client_id=-1;
}
}
void print_clnt_data(struct client_data* msg){
printf("printing client_data\n");
printf("client_data:\n\tclient_id:%d\n\tdestaddr(%s)\n\t", msg->client_id, inet_ntoa(msg->destaddr.sin_addr));
print_clnt_msg(&msg->msg);
}
void print_clnt_msg(struct client_msg* msg){
printf("client_msg:\n\t\t x:%g, y:%g, ts.tv_sec:%d\n", msg->x, msg->y, (int)msg->ts.tv_sec);
}