-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserverA.c
More file actions
189 lines (176 loc) · 5.18 KB
/
serverA.c
File metadata and controls
189 lines (176 loc) · 5.18 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
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#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>
#include <sys/wait.h>
#include "serverA.h"
int main(int argc, char const *argv[])
{
int backend_udp_sockfd = 0;
//struct addrinfo hints, *res, *p;
struct sockaddr_storage client_addr;
socklen_t addr_size = sizeof(client_addr);
int bytes = 0;
char send_buf[MAXBUFFERSIZE] = "";
char recv_buf[MAXBUFFERSIZE] = "";
char operation_buf[MAXLINELENGTH] = "";
signed long int *number_buffer = NULL;
number_buffer = (signed long int*)malloc(sizeof(signed long int) * 1000);
int nums_count = 0;
signed long long int result = 0;
/* create UDP socket on port number "21000" */
if (!(backend_udp_sockfd = udp_port_socket())){
fprintf(stderr, "Error: Server A failed to create UDP socket\n");
exit(1);
}
printf("The Server A is up and running using UDP on port %s\n", SERVER_A_PORT_NUM);
/*
In each round, the server will receive data from AWS and process it.
The data consists of a reduction type and many integers.
Then the server will send the result back to AWS using the same port number.
*/
while(1){
nums_count = 0;
if ((bytes = recvfrom(backend_udp_sockfd, recv_buf, sizeof(recv_buf), 0,
(struct sockaddr *)&client_addr, &addr_size)) == -1){
perror("server A: recvfrom");
exit(1);
}
recv_buf[bytes] = '\0';
/* get the reduction type ... */
strncpy(operation_buf, recv_buf, 3);
operation_buf[3] = '\0';
nums_count = process_number_buffer(recv_buf + 4, number_buffer);
printf("The Server A has received %d numbers\n", nums_count);
/* do computation ... */
result = 0;
if (!strcmp(operation_buf, "MAX")){
result = max_number(number_buffer, nums_count);
}
else if (!strcmp(operation_buf, "MIN")){
result = min_number(number_buffer, nums_count);
}
else if (!strcmp(operation_buf, "SUM")){
result = sum_number(number_buffer, nums_count);
}
else if (!strcmp(operation_buf, "SOS")){
result = sos_number(number_buffer, nums_count);
}
else{
fprintf(stderr, "Error: wrong reduction type %s\n", operation_buf);
continue;
}
printf("The Server A has successfully finished the reduction %s: %lli\n", operation_buf, result);
sprintf(send_buf, "%lli", result);
if ((bytes = sendto(backend_udp_sockfd, send_buf, strlen(send_buf), 0,
(struct sockaddr *)&client_addr, addr_size)) == -1){
perror("ServerA: sendto error");
exit(1);
}
printf("The Server A has successfully finished sending the reduction value to AWS server\n");
}
close(backend_udp_sockfd);
free(number_buffer);
return 0;
}
/*
create a UDP socket waiting at the corresponding port
The server X should ues the socket to communicate with AWS
*/
int udp_port_socket(){
int sockfd, rv;
struct addrinfo hints;
struct addrinfo *res, *p;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE;
if ( (rv = getaddrinfo(NULL, SERVER_A_PORT_NUM, &hints, &res)) != 0){
fprintf(stderr, "Error: AWS getaddrinfo failed: %s\n", gai_strerror(rv));
exit(1);
}
for (p = res; p != NULL; p = p->ai_next){
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
perror("Error: Server A UDP socket");
continue;
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
perror("server A: bind");
continue;
}
break;
}
if (NULL == p){
fprintf(stderr, "Error: Server A failed to create UDP socket\n");
exit(1);
}
freeaddrinfo(res);
res = NULL;
return sockfd;
}
/*
convert the string received from the UDP connection into signed long int list
*/
int process_number_buffer(char * number_buf, signed long int *number_list){
char *start_ptr = number_buf;
char *tab_ptr = strchr(start_ptr, '\n');
int nums_count = 0;
while(tab_ptr != NULL){
*(tab_ptr++) = '\0';
*(number_list + nums_count) = atol(start_ptr);
nums_count += 1;
start_ptr = tab_ptr;
tab_ptr = strchr(start_ptr, '\n');
}
return nums_count;
}
/*
do computation based on the reduction type and signed long int list
*/
signed long long int max_number(signed long int* number_list, int list_length){
int i;
signed long int current_max = 0, current_num;
for(i = 0; i < list_length; i++){
current_num = *(number_list + i);
if (current_num > current_max){
current_max = current_num;
}
}
return current_max;
}
signed long long int min_number(signed long int* number_list, int list_length){
int i;
signed long int current_min = 2147483647, current_num;
for(i = 0; i < list_length; i++){
current_num = *(number_list + i);
if (current_num < current_min){
current_min = current_num;
}
}
return current_min;
}
signed long long int sum_number(signed long int * number_list, int list_length){
int i;
signed long int sum = 0, current_num;
for (i = 0; i < list_length; i++){
current_num = *(number_list + i);
sum += current_num;
}
return sum;
}
signed long long int sos_number(signed long int * number_list, int list_length){
int i;
signed long int sos = 0, current_num;
for (i = 0; i < list_length; i++){
current_num = *(number_list + i);
sos += current_num * current_num;
}
return sos;
}