Created
November 30, 2017 17:10
-
-
Save splitline/2a35e3033d0d3264a56788cdcd4fdd38 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> | |
#include <pthread.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 (pre_acked <= NPACK) { | |
printf("===================\n"); | |
// initial | |
if(lastByteSent == 0){ | |
memset(buf, 0, BUFLEN); | |
sprintf(buf, "%d", send_buffer[lastByteSent]); | |
sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, (socklen_t) slen); | |
printf("send=%s\n", buf); | |
} | |
// Set Timeout | |
tv.tv_sec = 1; | |
tv.tv_usec = 0; | |
FD_ZERO(&readfds); | |
FD_SET(s, &readfds); | |
select(s + 1, &readfds, NULL, NULL, &tv); | |
if (!FD_ISSET(s, &readfds)) { | |
print_timeout(); | |
ssthresh = int(cwnd / 2); | |
cwnd = 1; | |
duplicate_ack = 0; | |
state = SLOW_START; | |
// fast retransmit | |
memset(buf, 0, BUFLEN); | |
sprintf(buf, "%d", send_buffer[acked]); | |
sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, (socklen_t) slen); | |
// printf("fast retransmit=%d\n", send_buffer[acked]); | |
continue; | |
} | |
else { | |
recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &recv_ip, (socklen_t*) &rlen); | |
acked = atoi(buf); | |
if (pre_acked == acked) { | |
duplicate_ack++; | |
if (duplicate_ack == 3) { | |
print_duplicate(); | |
ssthresh = cwnd / 2; | |
cwnd = ssthresh + 3; | |
state = FAST_RECOV; | |
// fast retransmit | |
memset(buf, 0, BUFLEN); | |
sprintf(buf, "%d", send_buffer[acked]); | |
sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, (socklen_t) slen); | |
// printf("fast retransmit=%d\n", send_buffer[acked]); | |
continue; | |
} | |
else { | |
print_cwnd(cwnd); | |
continue; | |
} | |
} | |
else { | |
pre_acked = acked; | |
duplicate_ack = 0; | |
if (state == SLOW_START) { | |
printf("(SLOW_START)ack=%s\n", buf); | |
cwnd++; | |
if (cwnd >= ssthresh) { | |
state = C_AVOID; | |
cwnd_count = 0; | |
} | |
} | |
else if (state == C_AVOID) { | |
printf("(C_AVOID)ack=%s\n", buf); | |
cwnd_count++; | |
if (cwnd_count >= cwnd) { | |
cwnd++; | |
cwnd_count = 0; | |
} | |
duplicate_ack = 0; | |
} | |
else if (state == FAST_RECOV) { | |
printf("(FAST_RECOV)ack=%s\n", buf); | |
cwnd = ssthresh; | |
state = C_AVOID; | |
duplicate_ack = 0; | |
} | |
print_cwnd(cwnd); | |
} | |
} | |
int count = 0; | |
for (int i = lastByteSent + 1; i < pre_acked + cwnd; i++) { | |
memset(buf, 0, BUFLEN); | |
sprintf(buf, "%d", send_buffer[i]); | |
sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, (socklen_t) slen); | |
// printf("send=%s\n", buf); | |
++count; | |
} | |
lastByteSent += count; | |
// 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