Skip to content

Instantly share code, notes, and snippets.

@splitline
Created November 30, 2017 17:10
Show Gist options
  • Save splitline/2a35e3033d0d3264a56788cdcd4fdd38 to your computer and use it in GitHub Desktop.
Save splitline/2a35e3033d0d3264a56788cdcd4fdd38 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>
#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