Last active
November 30, 2017 06:35
-
-
Save splitline/98bbb6f0343f9871f3c4cc526bc5067c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define SRV_IP "127.0.0.1" | |
#include <arpa/inet.h> | |
#include <netinet/in.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <unistd.h> | |
#include <string.h> | |
#define BUFLEN 512 | |
#define NPACK 50 | |
#define PORT 9930 | |
#define BUF_SIZE 1000 | |
#define SLOW_START 1 | |
#define C_AVOID 2 | |
#define FAST_RECOV 3 | |
/* diep(), #includes and #defines like in the server */ | |
struct sockaddr_in initial() { | |
struct sockaddr_in si_other; | |
memset((char *) &si_other, 0, sizeof(si_other)); | |
si_other.sin_family = AF_INET; | |
si_other.sin_port = htons(PORT); | |
if (inet_aton(SRV_IP, &si_other.sin_addr) == 0) { | |
fprintf(stderr, "inet_aton() failed\n"); | |
return si_other; | |
} | |
return si_other; | |
} | |
int connect_socket(void) { | |
int s; | |
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) | |
perror("socket"); | |
return s; | |
} | |
void close_socket(int s) { | |
close(s); | |
} | |
void print_cwnd(int cwnd) { | |
printf("CWND = %d\n", cwnd); | |
} | |
void print_duplicate() { | |
printf("3 duplicate ack\n"); | |
} | |
void print_timeout() { | |
printf("Time out\n"); | |
} | |
int main(void) { | |
struct sockaddr_in si_other, recv_ip; | |
int s, i, slen = sizeof(si_other), rlen = sizeof(recv_ip); | |
char buf[BUFLEN]; | |
struct timeval tv; | |
fd_set readfds; | |
si_other = initial(); | |
s = connect_socket(); | |
int send_buffer[NPACK + 1]; | |
int cwnd = 1; | |
double cwnd_double = 1.0; | |
int lastByteSent = 0; | |
int lastByteAcked = 0; | |
int ssthresh = 10; | |
int pre_acked; | |
int acked = 0; | |
int duplicate_ack = 0; | |
int state = SLOW_START; | |
for (i = 0; i < NPACK + 1; i++) { | |
send_buffer[i] = i; | |
} | |
/* Insert your codes below */ | |
memset(buf, 0, BUFLEN); | |
ssthresh = 10; | |
duplicate_ack = 0; | |
cwnd = 1; | |
cwnd_double = 1; | |
int cwnd_count = 0; | |
bool lose = true; | |
while (lastByteSent <= NPACK) { | |
memset(buf, 0, BUFLEN); | |
sprintf(buf, "%d", send_buffer[lastByteSent]); | |
sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, (socklen_t) slen); | |
// Set Timeout { | |
tv.tv_sec = 1; | |
tv.tv_usec = 0; | |
FD_ZERO(&readfds); | |
FD_SET(s, &readfds); | |
select(s + 1, &readfds, NULL, NULL, &tv); | |
// } Set Timeout | |
// if (lastByteSent == 3 && lose) {lastByteSent += 1;lose=!lose;} | |
// printf("\n\nsend=%s\n", buf); | |
switch (state) { | |
case SLOW_START: | |
if (!FD_ISSET(s, &readfds)) { | |
print_timeout(); | |
ssthresh = int(cwnd / 2); | |
cwnd = 1; | |
duplicate_ack = 0; | |
} | |
else { | |
recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &recv_ip, (socklen_t*) &rlen); | |
int ack = atoi(buf); | |
// printf("(SLOW_START)ack=%s\n", buf); | |
if (ack == pre_acked) { | |
duplicate_ack++; | |
if (duplicate_ack == 3 ) { | |
print_duplicate(); | |
lastByteSent-=3; | |
ssthresh = int(cwnd / 2); | |
state = FAST_RECOV; | |
continue; | |
} | |
} | |
else { | |
cwnd += 1; | |
duplicate_ack = 0; | |
print_cwnd(int(cwnd)); | |
} | |
pre_acked = ack; | |
++lastByteSent; | |
} | |
if (cwnd >= ssthresh) { | |
state = C_AVOID; | |
cwnd_count = 0; | |
} | |
break; | |
case C_AVOID: | |
if (!FD_ISSET(s, &readfds)) { | |
print_timeout(); | |
ssthresh = int(cwnd / 2); | |
cwnd = 1; | |
duplicate_ack = 0; | |
state = SLOW_START; | |
} | |
else { | |
recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &recv_ip, (socklen_t*) &rlen); | |
int ack = atoi(buf); | |
// printf("(C_AVOID)ack=%s\n", buf); | |
if (ack == pre_acked) { | |
duplicate_ack++; | |
if (duplicate_ack == 3) { | |
print_duplicate(); | |
ssthresh = int(cwnd / 2); | |
cwnd = ssthresh +3; | |
lastByteSent-=3; | |
state = FAST_RECOV; | |
continue; | |
} | |
} | |
else { | |
cwnd_count++; | |
if(cwnd_count >= cwnd){ | |
cwnd++; | |
cwnd_count=0; | |
} | |
duplicate_ack = 0; | |
print_cwnd(int(cwnd)); | |
} | |
++lastByteSent; | |
pre_acked = ack; | |
} | |
break; | |
case FAST_RECOV: | |
if (!FD_ISSET(s, &readfds)) { | |
print_timeout(); | |
ssthresh = int(cwnd / 2); | |
cwnd = 1; | |
duplicate_ack = 0; | |
state = SLOW_START; | |
} | |
else { | |
recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &recv_ip, (socklen_t*) &rlen); | |
int ack = atoi(buf); | |
// printf("(FAST_RECOV)ack=%s\n", buf); | |
if (ack == pre_acked) { | |
cwnd += 1; | |
} | |
else { | |
cwnd = ssthresh; | |
duplicate_ack = 0; | |
state = C_AVOID; | |
cwnd_count = 0; | |
++lastByteSent; | |
print_cwnd(int(cwnd)); | |
} | |
pre_acked = ack; | |
++lastByteSent; | |
} | |
break; | |
} | |
// printf("duplicate_ack=%d\n", duplicate_ack); | |
} | |
/* Insert your codes above */ | |
close_socket(s); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment