-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.c
159 lines (123 loc) · 2.92 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
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <stdarg.h>
#include "gbnpacket.c"
#define PORTNUM 6969
//prototypes
struct gbnpacket build_ack(int sequence_number);
int main(int argc, char *argv[]) {
if( argc != 4 ) {
printf("Usage: %s <server name> <output file name> <intentional drop>\n",
argv[0]);
exit(1);
}
//create socket
struct hostent *hp;
//The name of the server we're sending to is given as argv[1], it can
//be an ip address, or the colloquial name of the server (ie blanca or shavano)
if ((hp = gethostbyname(argv[1])) == 0 ) {
printf("Invalid or unknown host\n");
exit(1);
}
//Create our socket
int sk;
if ((sk = socket( PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("Problem creating socket\n");
exit(1);
}
FILE *file;
file = fopen(argv[2], "wb");
if (file == NULL) {
printf("file %s not valid!\n",
argv[2]);
exit(1);
}
double loss_rate;
loss_rate = atof(argv[3]);
srand((unsigned int)time(NULL));
int ld;
if ((ld = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("problem creating sock\n");
exit(1);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORTNUM);
if( bind(ld, (struct sockaddr *) &server, sizeof(server)) < 0) {
printf("Error binding\n");
exit(1);
}
int length = sizeof(server);
if (getsockname(ld, (struct sockaddr *) &server, &length)<0){
printf("Error getsockname\n");
exit(1);
}
printf("The server's UDP port number is %d\n", ntohs(server.sin_port));
struct sockaddr_in client;
int n=0;
int len = sizeof(client);
struct gbnpacket rsp_packet;
int sequence_number = 1;
while(1) {
struct gbnpacket current_packet;
n = recvfrom(
ld,
¤t_packet,
sizeof(current_packet),
0,
(struct sockaddr *) &client,
&len);
if(n>1) {
if(current_packet.type == 0) {
break;
}
if((double)rand()/RAND_MAX < loss_rate) {
printf("lost a packet\n");
continue; //lose this one
}
//build acknowledgement packet
rsp_packet = build_ack(current_packet.sequence_number);
sendto(
ld,
&rsp_packet,
sizeof(rsp_packet),
0,
(struct sockaddr *) &client,
sizeof(client));
//
if(rsp_packet.sequence_number == sequence_number) {
sequence_number++;
fwrite(
current_packet.data,
sizeof(current_packet.data[0]),
current_packet.length,
file);
}
}
}
return(0);
}
struct gbnpacket build_ack(int sequence_number) {
struct gbnpacket packet;
packet.type = 2;
packet.sequence_number = sequence_number;
packet.length = 0;
memset( packet.data, 0, PACKET_SIZE );
return packet;
}