Skip to content

Instantly share code, notes, and snippets.

@splitline
Last active November 30, 2017 06:35
Show Gist options
  • Save splitline/98bbb6f0343f9871f3c4cc526bc5067c to your computer and use it in GitHub Desktop.
Save splitline/98bbb6f0343f9871f3c4cc526bc5067c to your computer and use it in GitHub Desktop.
#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