Initial Import
This commit is contained in:
commit
dc58e0e2d5
11 changed files with 1327 additions and 0 deletions
43
Makefile
Normal file
43
Makefile
Normal file
|
@ -0,0 +1,43 @@
|
|||
CC := gcc
|
||||
LD := gcc
|
||||
|
||||
MODULES := api apps
|
||||
SRC_DIR := $(addprefix src/,$(MODULES)) src
|
||||
BUILD_DIR := $(addprefix build/,$(MODULES)) build
|
||||
|
||||
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
|
||||
OBJ := $(patsubst src/%.c,build/%.o,$(SRC))
|
||||
OBJ_CLI := $(patsubst build/apps/gateway.o,,$(patsubst build/apps/server.o,,$(OBJ)))
|
||||
OBJ_SERV := $(patsubst build/apps/gateway.o,,$(patsubst build/apps/client.o,,$(OBJ)))
|
||||
OBJ_GWAY := $(patsubst build/apps/server.o,,$(patsubst build/apps/client.o,,$(OBJ)))
|
||||
INCLUDES := include
|
||||
|
||||
vpath %.c $(SRC_DIR)
|
||||
|
||||
define make-goal
|
||||
$1/%.o: %.c
|
||||
$(CC) -m32 -g -I $(INCLUDES) -c $$< -o $$@
|
||||
endef
|
||||
|
||||
.PHONY: all checkdirs clean
|
||||
|
||||
all: checkdirs build/client build/server build/gateway
|
||||
|
||||
build/client: $(OBJ_CLI)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
|
||||
build/server: $(OBJ_SERV)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
|
||||
build/gateway: $(OBJ_GWAY)
|
||||
$(LD) -m32 $^ -o $@ -lpthread
|
||||
|
||||
checkdirs: $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
clean:
|
||||
@rm -rf $(BUILD_DIR)
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
|
31
include/api/mictcp_core.h
Normal file
31
include/api/mictcp_core.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef MICTCP_CORE_H
|
||||
#define MICTCP_CORE_H
|
||||
|
||||
#include <mictcp.h>
|
||||
#include <math.h>
|
||||
|
||||
// Public core functions, can be used for implementing mictcp
|
||||
int initialize_components(start_mode sm);
|
||||
|
||||
int IP_send(mic_tcp_pdu, mic_tcp_sock_addr);
|
||||
int IP_recv(mic_tcp_payload*, mic_tcp_sock_addr*, unsigned long delay);
|
||||
int app_buffer_get(mic_tcp_payload);
|
||||
int app_buffer_set(mic_tcp_payload);
|
||||
|
||||
void set_loss_rate(unsigned short);
|
||||
unsigned long get_now_time_msec();
|
||||
unsigned long get_now_time_usec();
|
||||
|
||||
// Private core functions, should not be used for implementing mictcp
|
||||
int full_send(mic_tcp_payload);
|
||||
int partial_send(mic_tcp_payload);
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu);
|
||||
mic_tcp_payload get_data_stream(mic_tcp_payload);
|
||||
mic_tcp_header get_header(char*);
|
||||
void* listening(void*);
|
||||
void print_header(mic_tcp_payload);
|
||||
|
||||
int min_size(int, int);
|
||||
float mod(int, float);
|
||||
|
||||
#endif
|
106
include/mictcp.h
Normal file
106
include/mictcp.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
#ifndef MICTCP_H
|
||||
#define MICTCP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
// Etats du protocole (les noms des états sont donnés à titre indicatif
|
||||
// et peuvent être modifiés)
|
||||
typedef enum protocol_state
|
||||
{
|
||||
IDLE, CLOSED, SYN_SENT, SYN_RECEIVED, ESTABLISHED, CLOSING
|
||||
} protocol_state;
|
||||
|
||||
// Mode de démarrage du protocole
|
||||
// NB : nécessaire à l’usage de la fonction initialize_components()
|
||||
typedef enum start_mode { CLIENT, SERVER } start_mode;
|
||||
|
||||
// Structure d’une adresse de socket
|
||||
typedef struct mic_tcp_sock_addr
|
||||
{
|
||||
char * ip_addr;
|
||||
int ip_addr_size;
|
||||
unsigned short port;
|
||||
} mic_tcp_sock_addr;
|
||||
|
||||
// Structure d'un socket
|
||||
typedef struct mic_tcp_sock
|
||||
{
|
||||
int fd; // descripteur du socket
|
||||
protocol_state state; // état du protocole
|
||||
mic_tcp_sock_addr addr; // adresse du socket
|
||||
} mic_tcp_sock;
|
||||
|
||||
// Structure des données utiles d’un PDU MIC-TCP
|
||||
typedef struct mic_tcp_payload
|
||||
{
|
||||
char* data; // données applicatives
|
||||
int size; // taille des données
|
||||
} mic_tcp_payload;
|
||||
|
||||
// Structure de l'entête d'un PDU MIC-TCP
|
||||
typedef struct mic_tcp_header
|
||||
{
|
||||
unsigned short source_port; // numéro de port source
|
||||
unsigned short dest_port; // numéro de port de destination
|
||||
unsigned int seq_num; // numéro de séquence
|
||||
unsigned int ack_num; // numéro d'acquittement
|
||||
unsigned char syn; // flag SYN (valeur 1 si activé et 0 si non)
|
||||
unsigned char ack; // flag ACK (valeur 1 si activé et 0 si non)
|
||||
unsigned char fin; // flag FIN (valeur 1 si activé et 0 si non)
|
||||
} mic_tcp_header;
|
||||
|
||||
// Structure d'un PDU MIC-TCP
|
||||
typedef struct mic_tcp_pdu
|
||||
{
|
||||
mic_tcp_header header ; // entête du PDU
|
||||
mic_tcp_payload payload; // charge utile du PDU ⇔ données applicatives
|
||||
} mic_tcp_pdu;
|
||||
|
||||
typedef struct app_buffer
|
||||
{
|
||||
mic_tcp_payload packet;
|
||||
struct app_buffer* next;
|
||||
unsigned short id;
|
||||
} app_buffer;
|
||||
|
||||
|
||||
// Fonctions de l'interface
|
||||
int mic_tcp_socket(start_mode sm);
|
||||
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr);
|
||||
int mic_tcp_accept(int socket, mic_tcp_sock_addr* addr);
|
||||
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr);
|
||||
int mic_tcp_send (int socket, char* mesg, int mesg_size);
|
||||
int mic_tcp_recv (int socket, char* mesg, int max_mesg_size);
|
||||
void process_received_PDU(mic_tcp_pdu pdu);
|
||||
int mic_tcp_close(int socket);
|
||||
|
||||
// Variables globales
|
||||
mic_tcp_sock local_sock_src;
|
||||
mic_tcp_sock local_sock_dest;
|
||||
unsigned long timer;
|
||||
unsigned long RTT1;
|
||||
unsigned long RTT2;
|
||||
int PE;
|
||||
int PA;
|
||||
float pourcentage_perte_client;
|
||||
float pourcentage_perte_serveur;
|
||||
float compteurDT;
|
||||
float DTperdu;
|
||||
mic_tcp_pdu DT;
|
||||
mic_tcp_pdu Syn;
|
||||
mic_tcp_pdu Ack;
|
||||
mic_tcp_pdu Syn_Ack;
|
||||
|
||||
#endif
|
326
src/api/mictcp_core.c
Normal file
326
src/api/mictcp_core.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
#include <api/mictcp_core.h>
|
||||
#include <pthread.h>
|
||||
|
||||
// API Variables
|
||||
int first_free = 0;
|
||||
int initialized = -1;
|
||||
int sys_socket;
|
||||
unsigned short API_CS_Port = 8524;
|
||||
unsigned short API_SC_Port = 8525;
|
||||
float reliability = 100;
|
||||
mic_tcp_sock current_socket;
|
||||
int exite_status = -1;
|
||||
pthread_t listen_th;
|
||||
pthread_mutex_t lock;
|
||||
unsigned int global_id = 0;
|
||||
unsigned short loss_rate = 0;
|
||||
float jump = 0;
|
||||
float range = 0;
|
||||
int count = 0;
|
||||
int reverse = 1;
|
||||
|
||||
struct sockaddr_in local_addr, remote_addr, tmp_addr;
|
||||
int local_size, remote_size, tmp_addr_size;
|
||||
|
||||
app_buffer* app_buffer_first = NULL;
|
||||
app_buffer* app_buffer_last = NULL;
|
||||
unsigned int app_buffer_size = 0;
|
||||
unsigned int app_buffer_count = 0;
|
||||
|
||||
// Fonctions Utilitaires
|
||||
|
||||
int initialize_components(start_mode mode)
|
||||
{
|
||||
int s;
|
||||
if(initialized != -1) return initialized;
|
||||
if((sys_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return -1;
|
||||
else initialized = 1;
|
||||
|
||||
if((mode == SERVER) & (initialized != -1))
|
||||
{
|
||||
memset((char *) &local_addr, 0, sizeof(local_addr));
|
||||
local_addr.sin_family = AF_INET;
|
||||
local_addr.sin_port = htons(API_CS_Port);
|
||||
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
int bnd = bind(sys_socket, (struct sockaddr *) &local_addr, sizeof(local_addr));
|
||||
|
||||
if (bnd == -1)
|
||||
{
|
||||
initialized = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(local_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_SC_Port);
|
||||
struct hostent * hp = gethostbyname("localhost");
|
||||
bcopy ( hp->h_addr, &(remote_addr.sin_addr.s_addr), hp->h_length);
|
||||
remote_size = sizeof(remote_addr);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(initialized != -1)
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(local_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_CS_Port);
|
||||
struct hostent * hp = gethostbyname("localhost");
|
||||
bcopy ( hp->h_addr, &(remote_addr.sin_addr.s_addr), hp->h_length);
|
||||
remote_size = sizeof(remote_addr);
|
||||
|
||||
memset((char *) &local_addr, 0, sizeof(local_addr));
|
||||
local_addr.sin_family = AF_INET;
|
||||
local_addr.sin_port = htons(API_SC_Port);
|
||||
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
int bnd = bind(sys_socket, (struct sockaddr *) &local_addr, sizeof(local_addr));
|
||||
}
|
||||
}
|
||||
|
||||
if((initialized == 1) && (mode == SERVER))
|
||||
{
|
||||
pthread_create (&listen_th, NULL, listening, "1");
|
||||
}
|
||||
|
||||
return initialized;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int IP_send(mic_tcp_pdu pk, mic_tcp_sock_addr addr)
|
||||
{
|
||||
if(initialized == -1) return -1;
|
||||
if(loss_rate == 0)
|
||||
{
|
||||
mic_tcp_payload tmp = get_full_stream(pk);
|
||||
int sent_size = full_send(tmp);
|
||||
|
||||
free (tmp.data);
|
||||
|
||||
return sent_size;
|
||||
}
|
||||
else return partial_send(get_full_stream(pk));
|
||||
}
|
||||
|
||||
int IP_recv(mic_tcp_payload* pk,mic_tcp_sock_addr* addr, unsigned long delay)
|
||||
{
|
||||
// Send data over a fake IP
|
||||
if(initialized == -1) return -1;
|
||||
|
||||
struct timeval tv;
|
||||
|
||||
if(delay == 0) {tv.tv_sec = 3600; tv.tv_usec = 0;}
|
||||
else {tv.tv_sec = 0; tv.tv_usec = delay;}
|
||||
if (setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
int recv_size = recvfrom(sys_socket, pk->data, pk->size, 0, (struct sockaddr *)&tmp_addr, &tmp_addr_size);
|
||||
pk->size = recv_size;
|
||||
return recv_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu pk)
|
||||
{
|
||||
// Get a full packet from data and header
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = 15 + pk.payload.size;
|
||||
tmp.data = malloc (tmp.size);
|
||||
|
||||
memcpy (tmp.data, &pk.header, 15);
|
||||
memcpy (tmp.data + 15, pk.payload.data, pk.payload.size);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_data_stream(mic_tcp_payload buff)
|
||||
{
|
||||
mic_tcp_payload tmp;
|
||||
tmp.data = malloc(buff.size-15);
|
||||
memcpy(tmp.data, buff.data+15, tmp.size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
mic_tcp_header get_header(char* packet)
|
||||
{
|
||||
// Get a struct header from an incoming packet
|
||||
mic_tcp_header tmp;
|
||||
memcpy(&tmp, packet, 15);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_data(mic_tcp_payload packet)
|
||||
{
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = packet.size - 15;
|
||||
tmp.data = malloc(tmp.size);
|
||||
memcpy(tmp.data, packet.data + 15, tmp.size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int full_send(mic_tcp_payload buff)
|
||||
{
|
||||
return sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, remote_size);
|
||||
}
|
||||
|
||||
int partial_send(mic_tcp_payload buff)
|
||||
{
|
||||
count ++;
|
||||
|
||||
if(range == 0)
|
||||
{
|
||||
jump = 1000.0 /((float) loss_rate);
|
||||
range += jump;
|
||||
}
|
||||
|
||||
|
||||
if(((int)range) == count)
|
||||
{
|
||||
reverse = -reverse;
|
||||
jump = 1000.0 /((float) loss_rate);
|
||||
range += jump + ( (jump / 4) * reverse);
|
||||
printf("\n -- Lost\n");
|
||||
return buff.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, remote_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int app_buffer_get(mic_tcp_payload app_buff)
|
||||
{
|
||||
while(app_buffer_count == 0)
|
||||
{
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
mic_tcp_payload tmp;
|
||||
|
||||
app_buffer* current;
|
||||
if(app_buffer_count > 0)
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
tmp.size = app_buffer_first->packet.size;
|
||||
tmp.data = app_buffer_first->packet.data;
|
||||
|
||||
current = app_buffer_first;
|
||||
if(app_buffer_count == 1)
|
||||
{
|
||||
app_buffer_first = app_buffer_last = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
app_buffer_first = app_buffer_first->next;
|
||||
}
|
||||
|
||||
memcpy(app_buff.data, tmp.data, min_size(tmp.size, app_buff.size));
|
||||
|
||||
app_buffer_size -= tmp.size;
|
||||
app_buffer_count --;
|
||||
free(current);
|
||||
free(tmp.data);
|
||||
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
return tmp.size;
|
||||
}
|
||||
}
|
||||
|
||||
int app_buffer_set(mic_tcp_payload bf)
|
||||
{
|
||||
|
||||
pthread_mutex_lock(&lock);
|
||||
|
||||
app_buffer* tmp = malloc(sizeof(app_buffer));
|
||||
tmp->packet.size = bf.size;
|
||||
tmp->packet.data = malloc(bf.size);
|
||||
tmp->id = global_id++;
|
||||
memcpy(tmp->packet.data, bf.data, bf.size);
|
||||
tmp->next = NULL;
|
||||
|
||||
if(app_buffer_count == 0)
|
||||
{
|
||||
app_buffer_first = app_buffer_last = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
app_buffer_last->next = tmp;
|
||||
app_buffer_last = tmp;
|
||||
}
|
||||
|
||||
app_buffer_size += bf.size;
|
||||
app_buffer_count ++;
|
||||
|
||||
pthread_mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* listening(void* arg)
|
||||
{
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
printf("[MICTCP-CORE] Demarrage du thread de reception reseau...\n");
|
||||
|
||||
mic_tcp_payload tmp_buff;
|
||||
tmp_buff.size = 1500;
|
||||
tmp_buff.data = malloc(1500);
|
||||
|
||||
mic_tcp_pdu pdu_tmp;
|
||||
int recv_size;
|
||||
mic_tcp_sock_addr remote;
|
||||
|
||||
while(1)
|
||||
{
|
||||
tmp_buff.size = 1500;
|
||||
recv_size = IP_recv(&tmp_buff, &remote, 0);
|
||||
|
||||
if(recv_size > 0)
|
||||
{
|
||||
pdu_tmp.header = get_header (tmp_buff.data);
|
||||
pdu_tmp.payload = get_data (tmp_buff);
|
||||
process_received_PDU(pdu_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void set_loss_rate(unsigned short rate)
|
||||
{
|
||||
loss_rate = rate;
|
||||
}
|
||||
|
||||
void print_header(mic_tcp_payload bf)
|
||||
{
|
||||
mic_tcp_header hd = get_header(bf.data);
|
||||
printf("\nSP: %d, DP: %d, SEQ: %d, ACK: %d, Count: %d, Size: %d.", hd.source_port, hd.dest_port, hd.seq_num, hd.ack_num, app_buffer_count, app_buffer_size);
|
||||
}
|
||||
|
||||
unsigned long get_now_time_msec()
|
||||
{
|
||||
return ((unsigned long) (get_now_time_usec() / 1000));
|
||||
}
|
||||
|
||||
unsigned long get_now_time_usec()
|
||||
{
|
||||
struct timeval now_time;
|
||||
gettimeofday(&now_time, NULL);
|
||||
return ((unsigned long)(now_time.tv_usec +(now_time.tv_sec * 1000000)));
|
||||
}
|
||||
|
||||
int min_size(int s1, int s2)
|
||||
{
|
||||
if(s1 <= s2) return s1;
|
||||
return s2;
|
||||
}
|
46
src/apps/client.c
Normal file
46
src/apps/client.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <mictcp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_SIZE 1000
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int sockfd = 0;
|
||||
mic_tcp_sock_addr addr;
|
||||
addr.ip_addr = "127.0.0.1";
|
||||
addr.port = 1234;
|
||||
|
||||
if ((sockfd = mic_tcp_socket(CLIENT)) == -1)
|
||||
{
|
||||
printf("[TSOCK] Erreur a la creation du socket MICTCP!\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TSOCK] Creation du socket MICTCP: OK\n");
|
||||
}
|
||||
|
||||
if (mic_tcp_connect(sockfd, addr) == -1)
|
||||
{
|
||||
printf("[TSOCK] Erreur a la connexion du socket MICTCP!\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TSOCK] Connexion du socket MICTCP: OK\n");
|
||||
}
|
||||
|
||||
char chaine[MAX_SIZE];
|
||||
memset(chaine, 0, MAX_SIZE);
|
||||
|
||||
printf("[TSOCK] Entrez vos message a envoyer, CTRL+D pour quitter\n");
|
||||
while(fgets(chaine, MAX_SIZE , stdin) != NULL) {
|
||||
int sent_size = mic_tcp_send(sockfd, chaine, strlen(chaine)+1);
|
||||
printf("[TSOCK] Appel de mic_send avec un message de taille : %d\n", strlen(chaine)+1);
|
||||
printf("[TSOCK] Appel de mic_send valeur de retour : %d\n", sent_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
544
src/apps/gateway.c
Normal file
544
src/apps/gateway.c
Normal file
|
@ -0,0 +1,544 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <mictcp.h>
|
||||
|
||||
|
||||
extern errno;
|
||||
|
||||
#define MAX_UDP_SEGMENT_SIZE 1480
|
||||
#define CUMULATED_BUFF_NB 1
|
||||
|
||||
/**
|
||||
* Function that performs UDP to TCP behavioral adaptation making it look like TCP was used.
|
||||
* Losses can be emulated by setting the loss paramter to 1.
|
||||
* returns void
|
||||
*/
|
||||
void udp_to_tcp(struct sockaddr_in listen_on, struct sockaddr_in transmit_to, int loss) {
|
||||
|
||||
// Define the socket on which we listen and which we use for sending packets out
|
||||
int listen_sockfd;
|
||||
|
||||
// A buffer used to store received segments before they are forwarded
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE];
|
||||
|
||||
|
||||
// Addresses for the work to be performed
|
||||
struct sockaddr_in serv_addr = listen_on;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// We construct the socket to be used by this function
|
||||
listen_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
printf("ERROR on binding: ");
|
||||
perror(0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
listen(listen_sockfd,5);
|
||||
|
||||
|
||||
// Initialize a packet count variable used when loss emulation is active
|
||||
int count = 0;
|
||||
ssize_t n = -1;
|
||||
|
||||
// Main activity loop, we never exit this, user terminates with SIGKILL
|
||||
while(1) {
|
||||
bzero(buffer,MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
n = recvfrom(listen_sockfd, buffer, MAX_UDP_SEGMENT_SIZE, 0, (struct sockaddr *) &cliaddr, &len);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
|
||||
if(loss == 1) {
|
||||
// We emulate losses every 600 packets by delaying the processing by 2 seconds.
|
||||
if(count++ == 600) {
|
||||
printf("Simulating TCP loss\n");
|
||||
sleep(2);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We forward the packet to its final destination
|
||||
n = sendto(listen_sockfd, buffer, n, 0, (struct sockaddr *) &transmit_to, len);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
}
|
||||
|
||||
// We never execute this but anyway, for sanity
|
||||
close(listen_sockfd);
|
||||
}
|
||||
|
||||
struct timespec tsSubtract (struct timespec time1, struct timespec time2) {
|
||||
struct timespec result ;
|
||||
|
||||
/* Subtract the second time from the first. */
|
||||
if ((time1.tv_sec < time2.tv_sec) || ((time1.tv_sec == time2.tv_sec) &&
|
||||
(time1.tv_nsec <= time2.tv_nsec))) {
|
||||
/* TIME1 <= TIME2? */
|
||||
result.tv_sec = result.tv_nsec = 0 ;
|
||||
} else { /* TIME1 > TIME2 */
|
||||
result.tv_sec = time1.tv_sec - time2.tv_sec ;
|
||||
if (time1.tv_nsec < time2.tv_nsec) {
|
||||
result.tv_nsec = time1.tv_nsec + 1000000000L - time2.tv_nsec ;
|
||||
result.tv_sec-- ; /* Borrow a second. */
|
||||
} else {
|
||||
result.tv_nsec = time1.tv_nsec - time2.tv_nsec ;
|
||||
}
|
||||
}
|
||||
|
||||
return (result) ;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that emulates TCP behavior while reading a file making it look like TCP was used.
|
||||
* Losses can be emulated by setting the loss paramter to 1.
|
||||
* returns void
|
||||
*/
|
||||
void file_to_tcp(struct sockaddr_in listen_on, struct sockaddr_in transmit_to, int loss) {
|
||||
|
||||
// Define the socket on which we listen and which we use for sending packets out
|
||||
int listen_sockfd;
|
||||
|
||||
// A buffer used to store received segments before they are forwarded
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE];
|
||||
|
||||
// Addresses for the work to be performed
|
||||
struct sockaddr_in serv_addr = listen_on;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// We construct the socket to be used by this function
|
||||
listen_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
//if (bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
// printf("ERROR on binding: ");
|
||||
// perror(0);
|
||||
// printf("\n");
|
||||
//}
|
||||
|
||||
//listen(listen_sockfd,5);
|
||||
|
||||
|
||||
// Initialize a packet count variable used when loss emulation is active
|
||||
int count = 0;
|
||||
ssize_t n = -1;
|
||||
|
||||
FILE * fd = fopen("../video/video.bin", "rb");
|
||||
|
||||
struct timespec currentTime;
|
||||
struct timespec lastTime;
|
||||
struct timespec rem;
|
||||
int firstValue = 0;
|
||||
|
||||
// Main activity loop, we never exit this, user terminates with SIGKILL
|
||||
while(!feof(fd)) {
|
||||
bzero(buffer,MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
n = fread(¤tTime, 1, sizeof(struct timespec), fd);
|
||||
if(firstValue > 0) {
|
||||
// We need to sleep a while
|
||||
struct timespec difference = tsSubtract(currentTime, lastTime);
|
||||
nanosleep(&difference, &rem);
|
||||
} else {
|
||||
firstValue++;
|
||||
}
|
||||
lastTime = currentTime;
|
||||
n = fread(buffer, 1, sizeof(n), fd);
|
||||
n = fread(buffer, 1, *((int *)buffer), fd);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
|
||||
if(loss == 1) {
|
||||
// We emulate losses every 600 packets by delaying the processing by 2 seconds.
|
||||
if(count++ == 600) {
|
||||
printf("Simulating TCP loss\n");
|
||||
sleep(2);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We forward the packet to its final destination
|
||||
n = sendto(listen_sockfd, buffer, n, 0, (struct sockaddr *) &transmit_to, len);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
}
|
||||
|
||||
// We never execute this but anyway, for sanity
|
||||
close(listen_sockfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that reads a file and delivers to MICTCP.
|
||||
* returns void
|
||||
*/
|
||||
void file_to_mictcp(struct sockaddr_in listen_on, struct sockaddr_in transmit_to) {
|
||||
|
||||
// Define the socket on which we listen
|
||||
int listen_sockfd;
|
||||
|
||||
// A buffer used to store received segments before they are forwarded
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE];
|
||||
|
||||
// Addresses for the work to be performed
|
||||
struct sockaddr_in serv_addr = listen_on;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// MICTCP stuff
|
||||
int mic_tcp_sockfd;
|
||||
start_mode start_mode_mic_tcp = CLIENT;
|
||||
mic_tcp_sock_addr mic_tcp_dest_addr;
|
||||
mic_tcp_dest_addr.ip_addr = (char* ) &(transmit_to.sin_addr.s_addr);
|
||||
mic_tcp_dest_addr.port = transmit_to.sin_port;
|
||||
|
||||
// We construct the UDP and MICTCP sockets to be used by this function
|
||||
listen_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if((mic_tcp_sockfd = mic_tcp_socket(start_mode_mic_tcp)) == -1) {
|
||||
printf("ERROR creating the MICTCP socket\n");
|
||||
}
|
||||
|
||||
// We now connect the MICTCP socket
|
||||
if(mic_tcp_connect(mic_tcp_sockfd, mic_tcp_dest_addr) == -1) {
|
||||
printf("ERROR connecting the MICTCP socket\n");
|
||||
}
|
||||
|
||||
// if (bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
// printf("ERROR on binding the UDP socket: ");
|
||||
// perror(0);
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
// listen(listen_sockfd,5);
|
||||
|
||||
|
||||
// Initialize a packet count variable used when loss emulation is active
|
||||
int count = 0;
|
||||
ssize_t n = -1;
|
||||
|
||||
FILE * fd = fopen("../video/video.bin", "rb");
|
||||
|
||||
struct timespec currentTimeFile;
|
||||
struct timespec firstTimeFile;
|
||||
struct timespec lastTimeFile;
|
||||
struct timespec timeFirstPacket;
|
||||
struct timespec currentTime;
|
||||
struct timespec rem;
|
||||
int firstValue = 0;
|
||||
|
||||
// Main activity loop, we never exit this, user terminates with SIGKILL
|
||||
while(1) {
|
||||
bzero(buffer, MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
n = fread(¤tTimeFile, 1, sizeof(struct timespec), fd);
|
||||
if(firstValue > 0) {
|
||||
// We need to sleep a while
|
||||
if( clock_gettime( CLOCK_REALTIME, ¤tTime) == -1 ) {
|
||||
perror( "clock gettime" );
|
||||
}
|
||||
struct timespec timeSinceFirstPacket = tsSubtract(currentTime, timeFirstPacket);
|
||||
struct timespec timeSinceFirstTimeFile = tsSubtract(currentTimeFile, firstTimeFile);
|
||||
struct timespec difference = tsSubtract(timeSinceFirstTimeFile, timeSinceFirstPacket);
|
||||
nanosleep(&difference, &rem);
|
||||
} else {
|
||||
firstTimeFile = currentTimeFile;
|
||||
if( clock_gettime( CLOCK_REALTIME, &timeFirstPacket) == -1 ) {
|
||||
perror( "clock gettime" );
|
||||
}
|
||||
firstValue++;
|
||||
}
|
||||
lastTimeFile = currentTimeFile;
|
||||
n = fread(buffer, 1, sizeof(n), fd);
|
||||
n = fread(buffer, 1, *((int *)buffer), fd);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
|
||||
// We forward the packet to its final destination
|
||||
n = mic_tcp_send(mic_tcp_sockfd, buffer, n);
|
||||
if (n <= 0) {
|
||||
printf("ERROR on MICTCP send\n");
|
||||
}
|
||||
}
|
||||
|
||||
// We never execute this but anyway, for sanity
|
||||
close(listen_sockfd);
|
||||
|
||||
// Same for MICTCP
|
||||
mic_tcp_close(mic_tcp_sockfd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function that listens on UDP and delivers to MICTCP.
|
||||
* returns void
|
||||
*/
|
||||
void udp_to_mictcp(struct sockaddr_in listen_on, struct sockaddr_in transmit_to) {
|
||||
|
||||
// Define the socket on which we listen
|
||||
int listen_sockfd;
|
||||
|
||||
// A buffer used to store received segments before they are forwarded
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE];
|
||||
|
||||
// Addresses for the work to be performed
|
||||
struct sockaddr_in serv_addr = listen_on;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// MICTCP stuff
|
||||
int mic_tcp_sockfd;
|
||||
start_mode start_mode_mic_tcp = CLIENT;
|
||||
mic_tcp_sock_addr mic_tcp_dest_addr;
|
||||
mic_tcp_dest_addr.ip_addr = (char* ) &(transmit_to.sin_addr.s_addr);
|
||||
mic_tcp_dest_addr.port = transmit_to.sin_port;
|
||||
|
||||
// We construct the UDP and MICTCP sockets to be used by this function
|
||||
listen_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if((mic_tcp_sockfd = mic_tcp_socket(start_mode_mic_tcp)) == -1) {
|
||||
printf("ERROR creating the MICTCP socket\n");
|
||||
}
|
||||
|
||||
// We now connect the MICTCP socket
|
||||
if(mic_tcp_connect(mic_tcp_sockfd, mic_tcp_dest_addr) == -1) {
|
||||
printf("ERROR connecting the MICTCP socket\n");
|
||||
}
|
||||
|
||||
if (bind(listen_sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
|
||||
printf("ERROR on binding the UDP socket: ");
|
||||
perror(0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
listen(listen_sockfd,5);
|
||||
|
||||
|
||||
// Initialize a packet count variable used when loss emulation is active
|
||||
int count = 0;
|
||||
ssize_t n = -1;
|
||||
|
||||
// Main activity loop, we never exit this, user terminates with SIGKILL
|
||||
while(1) {
|
||||
bzero(buffer, MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
n = recvfrom(listen_sockfd, buffer, MAX_UDP_SEGMENT_SIZE, 0, (struct sockaddr *) &cliaddr, &len);
|
||||
if (n < 0) {
|
||||
perror(0);
|
||||
}
|
||||
|
||||
// We forward the packet to its final destination
|
||||
n = mic_tcp_send(mic_tcp_sockfd, buffer, n);
|
||||
if (n <= 0) {
|
||||
printf("ERROR on MICTCP send\n");
|
||||
}
|
||||
}
|
||||
|
||||
// We never execute this but anyway, for sanity
|
||||
close(listen_sockfd);
|
||||
|
||||
// Same for MICTCP
|
||||
mic_tcp_close(mic_tcp_sockfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that listens on MICTCP and delivers to UDP.
|
||||
* returns void
|
||||
*/
|
||||
void mictcp_to_udp(struct sockaddr_in listen_on, struct sockaddr_in transmit_to) {
|
||||
|
||||
// Define the socket on which we listen
|
||||
int sending_sockfd;
|
||||
|
||||
// A buffer used to store received segments before they are forwarded
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE];
|
||||
int rcv_values [CUMULATED_BUFF_NB];
|
||||
char* Buff [CUMULATED_BUFF_NB];
|
||||
int iii;
|
||||
for (iii=0; iii<CUMULATED_BUFF_NB; iii++)
|
||||
{
|
||||
Buff[iii] = malloc(MAX_UDP_SEGMENT_SIZE);
|
||||
}
|
||||
|
||||
// Addresses for the work to be performed
|
||||
struct sockaddr_in serv_addr = listen_on;
|
||||
struct sockaddr_in cliaddr;
|
||||
socklen_t len = sizeof(cliaddr);
|
||||
|
||||
// MICTCP stuff
|
||||
int mic_tcp_sockfd;
|
||||
start_mode start_mode_mic_tcp = SERVER;
|
||||
mic_tcp_sock_addr mic_tcp_listen_addr, mic_tcp_remote_addr;
|
||||
mic_tcp_listen_addr.ip_addr = (char* ) &(listen_on.sin_addr.s_addr);
|
||||
mic_tcp_listen_addr.port = listen_on.sin_port;
|
||||
|
||||
// We construct the UDP and MICTCP sockets to be used by this function
|
||||
sending_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if((mic_tcp_sockfd = mic_tcp_socket(start_mode_mic_tcp)) == -1) {
|
||||
printf("ERROR creating the MICTCP socket\n");
|
||||
}
|
||||
|
||||
if (mic_tcp_bind(mic_tcp_sockfd, mic_tcp_listen_addr) == -1) {
|
||||
printf("ERROR on binding the MICTCP socket\n");
|
||||
}
|
||||
|
||||
if(mic_tcp_accept(mic_tcp_sockfd, &mic_tcp_remote_addr) == -1) {
|
||||
printf("ERROR on accept on the MICTCP socket\n");
|
||||
}
|
||||
|
||||
// Initialize a packet count variable used when loss emulation is active
|
||||
int count = 0;
|
||||
ssize_t n = -1;
|
||||
|
||||
// Main activity loop, we never exit this, user terminates with SIGKILL
|
||||
while(1) {
|
||||
int k;
|
||||
for(k=0; k<CUMULATED_BUFF_NB; k++)
|
||||
{
|
||||
bzero(Buff[k], MAX_UDP_SEGMENT_SIZE);
|
||||
}
|
||||
|
||||
for(k=0; k<CUMULATED_BUFF_NB; k++)
|
||||
{
|
||||
n = mic_tcp_recv(mic_tcp_sockfd, Buff[k], MAX_UDP_SEGMENT_SIZE);
|
||||
if (n <= 0) {
|
||||
printf("ERROR on mic_recv on the MICTCP socket\n");
|
||||
}
|
||||
}
|
||||
|
||||
// We forward the packet to its final destination
|
||||
for(k=0; k<CUMULATED_BUFF_NB; k++)
|
||||
{
|
||||
n = sendto(sending_sockfd, Buff[k], n, 0, (struct sockaddr *) &transmit_to, len);
|
||||
if (n <= 0) {
|
||||
perror(0);
|
||||
}
|
||||
}
|
||||
|
||||
//sleep(1);
|
||||
}
|
||||
|
||||
// We never execute this but anyway, for sanity
|
||||
close(sending_sockfd);
|
||||
|
||||
// Same for MICTCP
|
||||
mic_tcp_close(mic_tcp_sockfd);
|
||||
}
|
||||
|
||||
|
||||
static void usage(void) {
|
||||
printf("usage: gateway [-p|-s][-t tcp|mictcp] (<server>) <port>\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
|
||||
// Should losses be emulated?
|
||||
int loss = 1;
|
||||
int transport = 0;
|
||||
int puits = -1;
|
||||
|
||||
// What sockaddr should this program listen on?
|
||||
// Always on port 1234 (data from VLC arrives there using UDP)
|
||||
struct sockaddr_in serv_addr;
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
serv_addr.sin_port = htons(1234);
|
||||
|
||||
// Where should this program send the received data?
|
||||
struct sockaddr_in dest_addr;
|
||||
bzero((char *) &dest_addr, sizeof(dest_addr));
|
||||
dest_addr.sin_family = AF_INET;
|
||||
struct hostent * hp = gethostbyname("127.0.0.1");
|
||||
bcopy ( hp->h_addr, &(dest_addr.sin_addr.s_addr), hp->h_length);
|
||||
dest_addr.sin_port = htons(1234);
|
||||
|
||||
extern int optind;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "t:sp")) != -1) {
|
||||
switch (ch) {
|
||||
case 't':
|
||||
if(strcmp(optarg, "mictcp") == 0) {
|
||||
transport = 1;
|
||||
} else if(strcmp(optarg, "tcp") == 0) {
|
||||
transport = 0;
|
||||
} else {
|
||||
printf("Unrecognized transport : %s\n", optarg);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if(puits == -1) {
|
||||
puits = 0;
|
||||
} else {
|
||||
puits = -2;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if(puits == -1) {
|
||||
puits = 1;
|
||||
} else {
|
||||
puits = -2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(puits < 0) {
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if((puits == 1 && argc != 1) || ((puits == 0) && argc != 2)) {
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(puits == 0) {
|
||||
hp = gethostbyname(argv[0]);
|
||||
bcopy ( hp->h_addr, &(dest_addr.sin_addr.s_addr), hp->h_length);
|
||||
dest_addr.sin_port = htons(atoi(argv[1]));
|
||||
} else {
|
||||
serv_addr.sin_port = htons(atoi(argv[0]));
|
||||
}
|
||||
|
||||
if(transport == 0) {
|
||||
if(puits == 0) {
|
||||
// We receive on UDP and emulate TCP behavior before sending the data out
|
||||
file_to_tcp(serv_addr, dest_addr, loss);
|
||||
} else {
|
||||
printf("No gateway needed for puits using UDP\n");
|
||||
}
|
||||
} else if(transport == 1) {
|
||||
if(puits == 0) {
|
||||
// We receive on UDP and send the data using MICTCP
|
||||
file_to_mictcp(serv_addr, dest_addr);
|
||||
} else {
|
||||
// We receive on MICTCP and send the data using UDP
|
||||
mictcp_to_udp(serv_addr, dest_addr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
58
src/apps/server.c
Normal file
58
src/apps/server.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <mictcp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_SIZE 1000
|
||||
|
||||
int main()
|
||||
{
|
||||
int sockfd;
|
||||
mic_tcp_sock_addr addr;
|
||||
addr.ip_addr = "127.0.0.1";
|
||||
addr.port = 1234;
|
||||
|
||||
mic_tcp_sock_addr remote_addr;
|
||||
|
||||
if ((sockfd = mic_tcp_socket(SERVER)) == -1)
|
||||
{
|
||||
printf("[TSOCK] Erreur a la creation du socket MICTCP!\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TSOCK] Creation du socket MICTCP: OK\n");
|
||||
}
|
||||
|
||||
if (mic_tcp_bind(sockfd, addr) == -1)
|
||||
{
|
||||
printf("[TSOCK] Erreur lors du bind du socket MICTCP!\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TSOCK] Bind du socket MICTCP: OK\n");
|
||||
}
|
||||
|
||||
if (mic_tcp_accept(sockfd, &remote_addr) == -1)
|
||||
{
|
||||
printf("[TSOCK] Erreur lors de l'accept sur le socket MICTCP!\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[TSOCK] Accept sur le socket MICTCP: OK\n");
|
||||
}
|
||||
|
||||
|
||||
char chaine[MAX_SIZE];
|
||||
memset(chaine, 0, MAX_SIZE);
|
||||
|
||||
printf("[TSOCK] Appuyez sur CTRL+C pour quitter ...\n");
|
||||
|
||||
while(1) {
|
||||
printf("[TSOCK] Attente d'une donnee, appel de mic_recv ...\n");
|
||||
int rcv_size = mic_tcp_recv(sockfd, chaine, MAX_SIZE);
|
||||
printf("[TSOCK] Reception d'un message de taille : %d\n", rcv_size);
|
||||
printf("[TSOCK] Message Recu : %s", chaine);
|
||||
}
|
||||
return 0;
|
||||
}
|
71
src/mictcp.c
Normal file
71
src/mictcp.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <mictcp.h>
|
||||
#include <api/mictcp_core.h>
|
||||
|
||||
int mic_tcp_socket(start_mode sm)
|
||||
// Permet de créer un socket entre l’application et MIC-TCP
|
||||
// Retourne le descripteur du socket ou bien -1 en cas d'erreur
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
initialize_components(sm); // Appel obligatoire
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr)
|
||||
// Permet d’attribuer une adresse à un socket. Retourne 0 si succès, et -1 en cas d’échec
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
}
|
||||
|
||||
int mic_tcp_accept(int socket, mic_tcp_sock_addr* addr)
|
||||
// Met l’application en état d'acceptation d’une requête de connexion entrante
|
||||
// Retourne 0 si succès, -1 si erreur
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr)
|
||||
// Permet de réclamer l’établissement d’une connexion
|
||||
// Retourne 0 si la connexion est établie, et -1 en cas d’échec
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mic_tcp_send (int mic_sock, char* mesg, int mesg_size)
|
||||
// Permet de réclamer l’envoi d’une donnée applicative
|
||||
// Retourne la taille des données envoyées, et -1 en cas d'erreur
|
||||
// Dans le cas de la vidéo, seul la source va envoyer au puits
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int mic_tcp_recv (int socket, char* mesg, int max_mesg_size)
|
||||
// Permet à l’application réceptrice de réclamer la récupération d’une donnée
|
||||
// stockée dans les buffers de réception du socket
|
||||
// Retourne le nombre d’octets lu ou bien -1 en cas d’erreur
|
||||
// NB : cette fonction fait appel à la fonction app_buffer_get()
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int mic_tcp_close (int socket)
|
||||
// Permet de réclamer la destruction d’un socket.
|
||||
// Engendre la fermeture de la connexion suivant le modèle de TCP.
|
||||
// Retourne 0 si tout se passe bien et -1 en cas d'erreur
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction : "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void process_received_PDU(mic_tcp_pdu pdu)
|
||||
// Gère le traitement d’un PDU MIC-TCP reçu (mise à jour des numéros de séquence
|
||||
// et d'acquittement, etc.) puis insère les données utiles du PDU dans le buffer
|
||||
// de réception du socket. Cette fonction utilise la fonction app_buffer_add().
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
}
|
40
tsock_texte
Normal file
40
tsock_texte
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
|
||||
puits=false
|
||||
sourc=false
|
||||
protocol="tcp"
|
||||
|
||||
usage() { echo "Usage: $0 [-p|-s]" 1>&2; exit 1; }
|
||||
|
||||
while getopts "pst:" o; do
|
||||
case "${o}" in
|
||||
p)
|
||||
puits=true
|
||||
;;
|
||||
s)
|
||||
sourc=true
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ([ "$puits" = true ] && [ "$sourc" = true ]) || ([ "$puits" = false ] && [ "$sourc" = false ]) ; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$puits" = true ]; then
|
||||
cd build
|
||||
./server
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ "$sourc" = true ]; then
|
||||
|
||||
cd build
|
||||
./client
|
||||
cd ..
|
||||
fi
|
||||
|
62
tsock_video
Normal file
62
tsock_video
Normal file
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
|
||||
puits=false
|
||||
sourc=false
|
||||
protocol="tcp"
|
||||
|
||||
usage() { echo "Usage: $0 [[-p|-s] [-t (tcp|mictcp)]" 1>&2; exit 1; }
|
||||
|
||||
while getopts "pst:" o; do
|
||||
case "${o}" in
|
||||
t)
|
||||
protocol=${OPTARG}
|
||||
if [ "$protocol" != "tcp" ] && [ "$protocol" != "mictcp" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
p)
|
||||
puits=true
|
||||
;;
|
||||
s)
|
||||
sourc=true
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ([ "$puits" = true ] && [ "$sourc" = true ]) || ([ "$puits" = false ] && [ "$sourc" = false ]) ; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$puits" = true ]; then
|
||||
|
||||
echo "Lancement du puits, protocole " $protocol
|
||||
cvlc rtp://127.0.0.1:1234 > /dev/null 2>&1 &
|
||||
|
||||
if [ "$protocol" = "mictcp" ]; then
|
||||
cd build
|
||||
./gateway -p -t $protocol 1234 &
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$sourc" = true ]; then
|
||||
|
||||
echo "Lancement de la source, protocol " $protocol
|
||||
cd build
|
||||
./gateway -s -t $protocol 127.0.0.1 1234 &
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo "Appuyez sur ENTREE pour arreter"
|
||||
read line
|
||||
|
||||
echo "Arret"
|
||||
killall -9 cvlc > /dev/null 2>&1
|
||||
killall -9 vlc > /dev/null 2>&1
|
||||
killall -9 gateway > /dev/null 2>&1
|
||||
|
BIN
video/video.bin
Normal file
BIN
video/video.bin
Normal file
Binary file not shown.
Loading…
Reference in a new issue