ajout base be reseau
This commit is contained in:
parent
6a07b16401
commit
7bd3dfca82
13 changed files with 1239 additions and 0 deletions
65
Makefile
Normal file
65
Makefile
Normal file
|
@ -0,0 +1,65 @@
|
|||
DATE := `date +'%Y%m%d'`
|
||||
TAG := moodle-$(USER)
|
||||
PORT := $(shell expr `id -u` % 2000 + 12487)
|
||||
PORT2 := $(shell expr $(PORT) + 1)
|
||||
|
||||
ifneq ($(tag),)
|
||||
TAG := $(TAG)-$(tag)
|
||||
endif
|
||||
|
||||
CC := gcc
|
||||
LD := gcc
|
||||
|
||||
TAR_FILENAME := $(DATE)-mictcp-$(TAG).tar.gz
|
||||
|
||||
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) -DAPI_CS_Port=$(PORT) -DAPI_SC_Port=$(PORT2) -std=gnu99 -Wall -g -I $(INCLUDES) -c $$< -o $$@
|
||||
endef
|
||||
|
||||
.PHONY: all checkdirs clean
|
||||
|
||||
all: checkdirs build/client build/server build/gateway
|
||||
|
||||
build/client: $(OBJ_CLI)
|
||||
$(LD) $^ -o $@ -lm -lpthread
|
||||
|
||||
build/server: $(OBJ_SERV)
|
||||
$(LD) $^ -o $@ -lm -lpthread
|
||||
|
||||
build/gateway: $(OBJ_GWAY)
|
||||
$(LD) $^ -o $@ -lm -lpthread
|
||||
|
||||
checkdirs: $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
clean:
|
||||
@rm -rf $(BUILD_DIR)
|
||||
|
||||
distclean:
|
||||
@rm -rf $(BUILD_DIR)
|
||||
@-rm -f *.tar.gz || true
|
||||
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call make-goal,$(bdir))))
|
||||
|
||||
dist:
|
||||
@tar --exclude=build --exclude=*tar.gz --exclude=.git* -czvf mictcp-bundle.tar.gz ../mictcp
|
||||
|
||||
prof:
|
||||
@tar --exclude=build --exclude=.*tar.gz --exclude=video -czvf $(TAR_FILENAME) ../mictcp
|
49
include/api/mictcp_core.h
Normal file
49
include/api/mictcp_core.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#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_pdu*, mic_tcp_sock_addr*, unsigned long timeout);
|
||||
int app_buffer_get(mic_tcp_payload);
|
||||
void app_buffer_put(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 *
|
||||
**********************************************************************/
|
||||
#ifndef API_CS_Port
|
||||
#define API_CS_Port 8524
|
||||
#endif
|
||||
#ifndef API_SC_Port
|
||||
#define API_SC_Port 8525
|
||||
#endif
|
||||
#define API_HD_Size 15
|
||||
|
||||
typedef struct ip_payload
|
||||
{
|
||||
char* data; /* données transport */
|
||||
int size; /* taille des données */
|
||||
} ip_payload;
|
||||
|
||||
int mic_tcp_core_send(mic_tcp_payload);
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu);
|
||||
mic_tcp_payload get_mic_tcp_data(ip_payload);
|
||||
mic_tcp_header get_mic_tcp_header(ip_payload);
|
||||
void* listening(void*);
|
||||
void print_header(mic_tcp_pdu);
|
||||
|
||||
int min_size(int, int);
|
||||
float mod(int, float);
|
||||
|
||||
#endif
|
105
include/mictcp.h
Normal file
105
include/mictcp.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
#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 */
|
||||
} 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, mic_tcp_sock_addr addr);
|
||||
int mic_tcp_close(int socket);
|
||||
|
||||
#endif
|
347
src/api/mictcp_core.c
Normal file
347
src/api/mictcp_core.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
#include <api/mictcp_core.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <strings.h>
|
||||
|
||||
/*****************
|
||||
* API Variables *
|
||||
*****************/
|
||||
int initialized = -1;
|
||||
int sys_socket;
|
||||
pthread_t listen_th;
|
||||
pthread_mutex_t lock;
|
||||
unsigned short loss_rate = 0;
|
||||
struct sockaddr_in remote_addr;
|
||||
|
||||
/* This is for the buffer */
|
||||
TAILQ_HEAD(tailhead, app_buffer_entry) app_buffer_head;
|
||||
struct tailhead *headp;
|
||||
struct app_buffer_entry {
|
||||
mic_tcp_payload bf;
|
||||
TAILQ_ENTRY(app_buffer_entry) entries;
|
||||
};
|
||||
|
||||
/* Condition variable used for passive wait when buffer is empty */
|
||||
pthread_cond_t buffer_empty_cond;
|
||||
|
||||
/*************************
|
||||
* Fonctions Utilitaires *
|
||||
*************************/
|
||||
int initialize_components(start_mode mode)
|
||||
{
|
||||
int bnd;
|
||||
struct hostent * hp;
|
||||
struct sockaddr_in local_addr;
|
||||
|
||||
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))
|
||||
{
|
||||
TAILQ_INIT(&app_buffer_head);
|
||||
pthread_cond_init(&buffer_empty_cond, 0);
|
||||
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);
|
||||
bnd = bind(sys_socket, (struct sockaddr *) &local_addr, sizeof(local_addr));
|
||||
|
||||
if (bnd == -1)
|
||||
{
|
||||
initialized = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_SC_Port);
|
||||
hp = gethostbyname("localhost");
|
||||
memcpy (&(remote_addr.sin_addr.s_addr), hp->h_addr, hp->h_length);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(initialized != -1)
|
||||
{
|
||||
memset((char *) &remote_addr, 0, sizeof(remote_addr));
|
||||
remote_addr.sin_family = AF_INET;
|
||||
remote_addr.sin_port = htons(API_CS_Port);
|
||||
hp = gethostbyname("localhost");
|
||||
memcpy (&(remote_addr.sin_addr.s_addr), hp->h_addr, hp->h_length);
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
|
||||
int result = 0;
|
||||
|
||||
if(initialized == -1) {
|
||||
result = -1;
|
||||
|
||||
} else {
|
||||
mic_tcp_payload tmp = get_full_stream(pk);
|
||||
int sent_size = mic_tcp_core_send(tmp);
|
||||
|
||||
free (tmp.data);
|
||||
|
||||
/* Correct the sent size */
|
||||
result = (sent_size == -1) ? -1 : sent_size - API_HD_Size;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int IP_recv(mic_tcp_pdu* pk, mic_tcp_sock_addr* addr, unsigned long timeout)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
struct timeval tv;
|
||||
struct sockaddr_in tmp_addr;
|
||||
socklen_t tmp_addr_size = sizeof(struct sockaddr);
|
||||
|
||||
/* Send data over a fake IP */
|
||||
if(initialized == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Compute the number of entire seconds */
|
||||
tv.tv_sec = timeout / 1000;
|
||||
/* Convert the remainder to microseconds */
|
||||
tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
|
||||
|
||||
/* Create a reception buffer */
|
||||
int buffer_size = API_HD_Size + pk->payload.size;
|
||||
char *buffer = malloc(buffer_size);
|
||||
|
||||
if ((setsockopt(sys_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) >= 0) {
|
||||
result = recvfrom(sys_socket, buffer, buffer_size, 0, (struct sockaddr *)&tmp_addr, &tmp_addr_size);
|
||||
}
|
||||
|
||||
if (result != -1) {
|
||||
/* Create the mic_tcp_pdu */
|
||||
memcpy (&(pk->header), buffer, API_HD_Size);
|
||||
pk->payload.size = result - API_HD_Size;
|
||||
memcpy (pk->payload.data, buffer + API_HD_Size, pk->payload.size);
|
||||
|
||||
/* Generate a stub address */
|
||||
if (addr != NULL) {
|
||||
addr->ip_addr = "localhost";
|
||||
addr->ip_addr_size = strlen(addr->ip_addr) + 1; // don't forget '\0'
|
||||
addr->port = pk->header.source_port;
|
||||
}
|
||||
|
||||
/* Correct the receved size */
|
||||
result -= API_HD_Size;
|
||||
}
|
||||
|
||||
/* Free the reception buffer */
|
||||
free(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_full_stream(mic_tcp_pdu pk)
|
||||
{
|
||||
/* Get a full packet from data and header */
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = API_HD_Size + pk.payload.size;
|
||||
tmp.data = malloc (tmp.size);
|
||||
|
||||
memcpy (tmp.data, &pk.header, API_HD_Size);
|
||||
memcpy (tmp.data + API_HD_Size, pk.payload.data, pk.payload.size);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
mic_tcp_payload get_mic_tcp_data(ip_payload buff)
|
||||
{
|
||||
mic_tcp_payload tmp;
|
||||
tmp.size = buff.size-API_HD_Size;
|
||||
tmp.data = malloc(tmp.size);
|
||||
memcpy(tmp.data, buff.data+API_HD_Size, tmp.size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
mic_tcp_header get_mic_tcp_header(ip_payload packet)
|
||||
{
|
||||
/* Get a struct header from an incoming packet */
|
||||
mic_tcp_header tmp;
|
||||
memcpy(&tmp, packet.data, API_HD_Size);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int full_send(mic_tcp_payload buff)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result = sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, sizeof(remote_addr));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int mic_tcp_core_send(mic_tcp_payload buff)
|
||||
{
|
||||
int random = rand();
|
||||
int result = buff.size;
|
||||
int lr_tresh = (int) round(((float)loss_rate/100.0)*RAND_MAX);
|
||||
|
||||
if(random > lr_tresh) {
|
||||
result = sendto(sys_socket, buff.data, buff.size, 0, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
|
||||
} else {
|
||||
printf("[MICTCP-CORE] Perte du paquet\n");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int app_buffer_get(mic_tcp_payload app_buff)
|
||||
{
|
||||
/* A pointer to a buffer entry */
|
||||
struct app_buffer_entry * entry;
|
||||
|
||||
/* The actual size passed to the application */
|
||||
int result = 0;
|
||||
|
||||
/* Lock a mutex to protect the buffer from corruption */
|
||||
pthread_mutex_lock(&lock);
|
||||
|
||||
/* If the buffer is empty, we wait for insertion */
|
||||
while(app_buffer_head.tqh_first == NULL) {
|
||||
pthread_cond_wait(&buffer_empty_cond, &lock);
|
||||
}
|
||||
|
||||
/* When we execute the code below, the following conditions are true:
|
||||
- The buffer contains at least 1 element
|
||||
- We hold the lock on the mutex
|
||||
*/
|
||||
|
||||
/* The entry we want is the first one in the buffer */
|
||||
entry = app_buffer_head.tqh_first;
|
||||
|
||||
/* How much data are we going to deliver to the application ? */
|
||||
result = min_size(entry->bf.size, app_buff.size);
|
||||
|
||||
/* We copy the actual data in the application allocated buffer */
|
||||
memcpy(app_buff.data, entry->bf.data, result);
|
||||
|
||||
/* We remove the entry from the buffer */
|
||||
TAILQ_REMOVE(&app_buffer_head, entry, entries);
|
||||
|
||||
/* Release the mutex */
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
/* Clean up memory */
|
||||
free(entry->bf.data);
|
||||
free(entry);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void app_buffer_put(mic_tcp_payload bf)
|
||||
{
|
||||
/* Prepare a buffer entry to store the data */
|
||||
struct app_buffer_entry * entry = malloc(sizeof(struct app_buffer_entry));
|
||||
entry->bf.size = bf.size;
|
||||
entry->bf.data = malloc(bf.size);
|
||||
memcpy(entry->bf.data, bf.data, bf.size);
|
||||
|
||||
/* Lock a mutex to protect the buffer from corruption */
|
||||
pthread_mutex_lock(&lock);
|
||||
|
||||
/* Insert the packet in the buffer, at the end of it */
|
||||
TAILQ_INSERT_TAIL(&app_buffer_head, entry, entries);
|
||||
|
||||
/* Release the mutex */
|
||||
pthread_mutex_unlock(&lock);
|
||||
|
||||
/* We can now signal to any potential thread waiting that the buffer is
|
||||
no longer empty */
|
||||
pthread_cond_broadcast(&buffer_empty_cond);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* listening(void* arg)
|
||||
{
|
||||
mic_tcp_pdu pdu_tmp;
|
||||
int recv_size;
|
||||
mic_tcp_sock_addr remote;
|
||||
|
||||
pthread_mutex_init(&lock, NULL);
|
||||
|
||||
printf("[MICTCP-CORE] Demarrage du thread de reception reseau...\n");
|
||||
|
||||
const int payload_size = 1500 - API_HD_Size;
|
||||
pdu_tmp.payload.size = payload_size;
|
||||
pdu_tmp.payload.data = malloc(payload_size);
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
pdu_tmp.payload.size = payload_size;
|
||||
recv_size = IP_recv(&pdu_tmp, &remote, 0);
|
||||
|
||||
if(recv_size != -1)
|
||||
{
|
||||
process_received_PDU(pdu_tmp, remote);
|
||||
} else {
|
||||
/* This should never happen */
|
||||
printf("Error in recv\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void set_loss_rate(unsigned short rate)
|
||||
{
|
||||
loss_rate = rate;
|
||||
}
|
||||
|
||||
void print_header(mic_tcp_pdu bf)
|
||||
{
|
||||
mic_tcp_header hd = bf.header;
|
||||
printf("\nSP: %d, DP: %d, SEQ: %d, ACK: %d", hd.source_port, hd.dest_port, hd.seq_num, hd.ack_num);
|
||||
}
|
||||
|
||||
unsigned long get_now_time_msec()
|
||||
{
|
||||
return ((unsigned long) (get_now_time_usec() / 1000));
|
||||
}
|
||||
|
||||
unsigned long get_now_time_usec()
|
||||
{
|
||||
struct timespec now_time;
|
||||
clock_gettime( CLOCK_REALTIME, &now_time);
|
||||
return ((unsigned long)((now_time.tv_nsec / 1000) + (now_time.tv_sec * 1000000)));
|
||||
}
|
||||
|
||||
int min_size(int s1, int s2)
|
||||
{
|
||||
if(s1 <= s2) return s1;
|
||||
return s2;
|
||||
}
|
48
src/apps/client.c
Normal file
48
src/apps/client.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <mictcp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_SIZE 1000
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
int sockfd = 0;
|
||||
char chaine[MAX_SIZE];
|
||||
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");
|
||||
}
|
||||
|
||||
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 : %lu\n", strlen(chaine)+1);
|
||||
printf("[TSOCK] Appel de mic_send valeur de retour : %d\n", sent_size);
|
||||
}
|
||||
|
||||
mic_tcp_close(sockfd);
|
||||
|
||||
return 0;
|
||||
}
|
371
src/apps/gateway.c
Normal file
371
src/apps/gateway.c
Normal file
|
@ -0,0 +1,371 @@
|
|||
#include <errno.h>
|
||||
#include <mictcp.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
//
|
||||
// Déclaration des types, constantes et macros
|
||||
//
|
||||
|
||||
#define ENABLE_TCP_LOSS 1
|
||||
#define MAX_UDP_SEGMENT_SIZE 1480
|
||||
#define MICTCP_PORT 1337
|
||||
#define VIDEO_FILE "../video/video.bin"
|
||||
|
||||
/**
|
||||
* Macro utilisée pour afficher le message d'erreur msg passé en paramètre
|
||||
* si la condition cond est validée, puis arrêter le programme.
|
||||
* Le message affiché contient des informations supplémentaires concernant
|
||||
* le fichier de provenance, la fonction et le numéro de ligne concerné.
|
||||
* Si errno est set, le message d'erreur associé est aussi affiché.
|
||||
*/
|
||||
#define ERROR_IF(cond,msg) \
|
||||
if (cond) { \
|
||||
if (errno != 0) { \
|
||||
fprintf(stderr, "%s:%d [%s()] -> %s (%s)\n", \
|
||||
__FILE__, __LINE__, __func__, msg, strerror(errno)); \
|
||||
} else { \
|
||||
fprintf(stderr, "%s:%d [%s()] -> %s\n", \
|
||||
__FILE__, __LINE__, __func__, msg); \
|
||||
} \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonctions du programme
|
||||
*/
|
||||
enum gateway_function {
|
||||
UND_FCT,
|
||||
SOURCE,
|
||||
PUITS
|
||||
};
|
||||
|
||||
/**
|
||||
* Protocoles pouvant être utilisé
|
||||
*/
|
||||
enum gateway_protocol {
|
||||
PROTO_TCP,
|
||||
PROTO_MICTCP
|
||||
};
|
||||
|
||||
//
|
||||
// Déclaration des fonctions locales
|
||||
//
|
||||
|
||||
static void file_to_faketcp(char* filename, char *host, int port);
|
||||
static void file_to_mictcp(char* filename);
|
||||
static void mictcp_to_udp(char *host, int port);
|
||||
static int read_rtp_packet(FILE *fd, struct timespec *timestamp, char *buffer, int buffer_size);
|
||||
static struct timespec tsSubtract(struct timespec time1, struct timespec time2);
|
||||
static void usage(void);
|
||||
|
||||
//
|
||||
// Corps des fonctions publiques
|
||||
//
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
enum gateway_protocol proto = PROTO_TCP;
|
||||
enum gateway_function func = UND_FCT;
|
||||
|
||||
int ch;
|
||||
while ((ch = getopt(argc, argv, "t:sp")) != -1) {
|
||||
switch (ch) {
|
||||
case 't':
|
||||
if (strcmp(optarg, "mictcp") == 0) {
|
||||
proto = PROTO_MICTCP;
|
||||
} else if (strcmp(optarg, "tcp") == 0) {
|
||||
proto = PROTO_TCP;
|
||||
} else {
|
||||
printf("Unrecognized transport : %s\n", optarg);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (func == UND_FCT) {
|
||||
func = SOURCE;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
if (func == UND_FCT) {
|
||||
func = PUITS;
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (func == UND_FCT || (func == PUITS && argc != 1) || (func == SOURCE && argc != 2)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (proto == PROTO_TCP) {
|
||||
if (func == SOURCE) {
|
||||
file_to_faketcp(VIDEO_FILE, argv[0], atoi(argv[1]));
|
||||
} else {
|
||||
printf("No gateway needed for puits using UDP\n");
|
||||
}
|
||||
} else {
|
||||
if (func == SOURCE) {
|
||||
file_to_mictcp(VIDEO_FILE);
|
||||
} else {
|
||||
mictcp_to_udp("127.0.0.1", atoi(argv[0]));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Corps des fonctions privées
|
||||
//
|
||||
|
||||
/**
|
||||
* Print usage and exit
|
||||
*/
|
||||
static void usage(void)
|
||||
{
|
||||
printf("usage: gateway [-p|-s][-t tcp|mictcp] (<server>) <port>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that emulates TCP behavior while reading a file making it look like TCP was used.
|
||||
*/
|
||||
static void file_to_faketcp(char* filename, char *host, int port)
|
||||
{
|
||||
/* Création du socket */
|
||||
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ERROR_IF(sockfd == -1, "Socket error");
|
||||
|
||||
/* Construction de l'adresse du socket distant */
|
||||
struct sockaddr_in s_addr = {0};
|
||||
s_addr.sin_family = AF_INET;
|
||||
s_addr.sin_port = htons(port);
|
||||
struct hostent* host_info = gethostbyname(host);
|
||||
ERROR_IF(host_info == NULL, "Error gethostbyname");
|
||||
ERROR_IF(host_info->h_addrtype != AF_INET, "gethostbyname bad h_addrtype");
|
||||
ERROR_IF(host_info->h_addr == NULL, "gethostbyname no addr");
|
||||
memcpy(&(s_addr.sin_addr), host_info->h_addr, host_info->h_length);
|
||||
|
||||
/* Ouverture du fichier vidéo */
|
||||
FILE *filefd = fopen(filename, "rb");
|
||||
ERROR_IF(filefd == NULL, "Error fopen");
|
||||
|
||||
uint count = 0; // compteur de paquets
|
||||
struct timespec current_time, last_time; // stockage des timestamps
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE]; // buffer de lecture/ecriture
|
||||
last_time.tv_sec = -1;
|
||||
last_time.tv_nsec = LONG_MAX;
|
||||
|
||||
/* Lecture jusqu'à la fin du fichier vidéo */
|
||||
while (!feof(filefd)) {
|
||||
|
||||
/* Lecture du paquet rtp */
|
||||
int nb_read = read_rtp_packet(filefd, ¤t_time, buffer, MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
/* Attente avant la prochaine lecture */
|
||||
struct timespec delay = tsSubtract(current_time, last_time);
|
||||
nanosleep(&delay, NULL);
|
||||
|
||||
/* Mise à jour du timestamp */
|
||||
last_time = current_time;
|
||||
|
||||
if (ENABLE_TCP_LOSS) {
|
||||
/* On émule les pertes de paquets en délayant l'envoi de 2 secondes */
|
||||
if (count++ == 600) {
|
||||
printf("Simulating TCP loss\n");
|
||||
sleep(2);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Envoi du paquet rtp via faketcp */
|
||||
int nb_sent = sendto(sockfd, buffer, nb_read, 0, (struct sockaddr*)&s_addr, sizeof(s_addr));
|
||||
ERROR_IF(nb_sent == -1, "Error sendto");
|
||||
}
|
||||
|
||||
/* Fermeture du socket et du fichier */
|
||||
close(sockfd);
|
||||
fclose(filefd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that reads a file and delivers to MICTCP.
|
||||
*/
|
||||
static void file_to_mictcp(char* filename)
|
||||
{
|
||||
/* Création du socket MICTCP */
|
||||
int sockfd = mic_tcp_socket(CLIENT);
|
||||
if (sockfd == -1) {
|
||||
printf("ERROR creating the MICTCP socket\n");
|
||||
}
|
||||
|
||||
/* On effectue la connexion */
|
||||
mic_tcp_sock_addr dest_addr;
|
||||
dest_addr.ip_addr = "localhost";
|
||||
dest_addr.ip_addr_size = strlen(dest_addr.ip_addr) + 1; // '\0'
|
||||
dest_addr.port = MICTCP_PORT;
|
||||
if (mic_tcp_connect(sockfd, dest_addr) == -1) {
|
||||
printf("ERROR connecting the MICTCP socket\n");
|
||||
}
|
||||
|
||||
/* Ouverture du fichier vidéo */
|
||||
FILE *filefd = fopen(filename, "rb");
|
||||
ERROR_IF(filefd == NULL, "Error fopen");
|
||||
|
||||
struct timespec current_time, last_time; // stockage des timestamps
|
||||
char buffer[MAX_UDP_SEGMENT_SIZE]; // buffer de lecture/ecriture
|
||||
last_time.tv_sec = -1;
|
||||
last_time.tv_nsec = LONG_MAX;
|
||||
|
||||
/* Lecture jusqu'à la fin du fichier vidéo */
|
||||
while (!feof(filefd)) {
|
||||
|
||||
/* Lecture du paquet rtp */
|
||||
int nb_read = read_rtp_packet(filefd, ¤t_time, buffer, MAX_UDP_SEGMENT_SIZE);
|
||||
|
||||
/* Attente avant la prochaine lecture */
|
||||
struct timespec delay = tsSubtract(current_time, last_time);
|
||||
nanosleep(&delay, NULL);
|
||||
|
||||
/* Mise à jour du timestamp */
|
||||
last_time = current_time;
|
||||
|
||||
/* Envoi du paquet rtp via mictcp */
|
||||
int nb_sent = mic_tcp_send(sockfd, buffer, nb_read);
|
||||
if (nb_sent < 0) {
|
||||
printf("ERROR on MICTCP send\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Fermeture du socket et du fichier */
|
||||
if (mic_tcp_close(sockfd) == -1) {
|
||||
printf("ERROR on MICTCP close\n");
|
||||
}
|
||||
fclose(filefd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that listens on MICTCP and delivers to UDP.
|
||||
*/
|
||||
static void mictcp_to_udp(char *host, int port)
|
||||
{
|
||||
/* Création du socket UDP */
|
||||
int udp_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
ERROR_IF(udp_sockfd == -1, "Socket error");
|
||||
|
||||
/* Construction de l'adresse du socket distant */
|
||||
struct sockaddr_in remote_s_addr = {0};
|
||||
remote_s_addr.sin_family = AF_INET;
|
||||
remote_s_addr.sin_port = htons(port);
|
||||
struct hostent* host_info = gethostbyname(host);
|
||||
ERROR_IF(host_info == NULL, "Error gethostbyname");
|
||||
ERROR_IF(host_info->h_addrtype != AF_INET, "gethostbyname bad h_addrtype");
|
||||
ERROR_IF(host_info->h_addr == NULL, "gethostbyname no addr");
|
||||
memcpy(&(remote_s_addr.sin_addr), host_info->h_addr, host_info->h_length);
|
||||
|
||||
/* Création du socket MICTCP */
|
||||
int mictcp_sockfd = mic_tcp_socket(SERVER);
|
||||
if (mictcp_sockfd == -1) {
|
||||
printf("ERROR creating the MICTCP socket\n");
|
||||
}
|
||||
|
||||
/* On bind le socket mictcp à une adresse locale */
|
||||
mic_tcp_sock_addr mt_local_addr;
|
||||
mt_local_addr.ip_addr = NULL;
|
||||
mt_local_addr.ip_addr_size = 0;
|
||||
mt_local_addr.port = MICTCP_PORT;
|
||||
if (mic_tcp_bind(mictcp_sockfd, mt_local_addr) == -1) {
|
||||
printf("ERROR on binding the MICTCP socket\n");
|
||||
}
|
||||
|
||||
/* Acceptation d'une demande de connexion */
|
||||
mic_tcp_sock_addr mt_remote_addr;
|
||||
if (mic_tcp_accept(mictcp_sockfd, &mt_remote_addr) == -1) {
|
||||
printf("ERROR on accept on the MICTCP socket\n");
|
||||
}
|
||||
|
||||
/* Lecture mictcp vers udp */
|
||||
char buff[MAX_UDP_SEGMENT_SIZE]; // buffer de lecture/ecriture
|
||||
while (1) {
|
||||
int nb_read = mic_tcp_recv(mictcp_sockfd, buff, MAX_UDP_SEGMENT_SIZE);
|
||||
if (nb_read <= 0) {
|
||||
if (nb_read < 0) {
|
||||
printf("ERROR on mic_recv on the MICTCP socket\n");
|
||||
}
|
||||
break; // Fin de la transmission
|
||||
}
|
||||
|
||||
int nb_sent = sendto(udp_sockfd, buff, nb_read, 0, (struct sockaddr*)&remote_s_addr, sizeof(remote_s_addr));
|
||||
ERROR_IF(nb_sent == -1, "Error sendto");
|
||||
}
|
||||
|
||||
/* Fermeture des sockets */
|
||||
if (mic_tcp_close(mictcp_sockfd) == -1) {
|
||||
printf("ERROR on MICTCP close\n");
|
||||
}
|
||||
close(udp_sockfd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one rtp packet from the video file in the buffer, as well as
|
||||
* the corresponding timestamp
|
||||
* Return the number of bytes read
|
||||
*/
|
||||
static int read_rtp_packet(FILE *fd, struct timespec *timestamp, char *buffer, int buffer_size)
|
||||
{
|
||||
/* Les champs du timestamp sont stockés sur 4 octets (héritage de la version 32 bits) */
|
||||
timestamp->tv_sec = 0;
|
||||
timestamp->tv_nsec = 0;
|
||||
fread(&(timestamp->tv_sec), 1, 4, fd);
|
||||
fread(&(timestamp->tv_nsec), 1, 4, fd);
|
||||
|
||||
/* Taille du packet rdp */
|
||||
int packet_size = 0;
|
||||
fread(&packet_size, 1, sizeof(int), fd);
|
||||
|
||||
/* Lecture du paquet rdp */
|
||||
ERROR_IF(packet_size > buffer_size, "Buffer is too small to store the packet");
|
||||
return fread(buffer, 1, packet_size, fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return (time1 - time2) when (time1 > time2), 0 otherwise
|
||||
*/
|
||||
static 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 = 0;
|
||||
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);
|
||||
}
|
60
src/apps/server.c
Normal file
60
src/apps/server.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include <mictcp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_SIZE 1000
|
||||
|
||||
int main()
|
||||
{
|
||||
int sockfd;
|
||||
mic_tcp_sock_addr addr;
|
||||
mic_tcp_sock_addr remote_addr;
|
||||
char chaine[MAX_SIZE];
|
||||
|
||||
addr.ip_addr = "127.0.0.1";
|
||||
addr.port = 1234;
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
memset(chaine, 0, MAX_SIZE);
|
||||
|
||||
printf("[TSOCK] Appuyez sur CTRL+C pour quitter ...\n");
|
||||
|
||||
while(1) {
|
||||
int rcv_size = 0;
|
||||
printf("[TSOCK] Attente d'une donnee, appel de mic_recv ...\n");
|
||||
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;
|
||||
}
|
90
src/mictcp.c
Normal file
90
src/mictcp.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <mictcp.h>
|
||||
#include <api/mictcp_core.h>
|
||||
|
||||
/*
|
||||
* Permet de créer un socket entre l’application et MIC-TCP
|
||||
* Retourne le descripteur du socket ou bien -1 en cas d'erreur
|
||||
*/
|
||||
int mic_tcp_socket(start_mode sm)
|
||||
{
|
||||
int result = -1;
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
result = initialize_components(sm); /* Appel obligatoire */
|
||||
set_loss_rate(0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Permet d’attribuer une adresse à un socket.
|
||||
* Retourne 0 si succès, et -1 en cas d’échec
|
||||
*/
|
||||
int mic_tcp_bind(int socket, mic_tcp_sock_addr addr)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Met le socket en état d'acceptation de connexions
|
||||
* Retourne 0 si succès, -1 si erreur
|
||||
*/
|
||||
int mic_tcp_accept(int socket, mic_tcp_sock_addr* addr)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Permet de réclamer l’établissement d’une connexion
|
||||
* Retourne 0 si la connexion est établie, et -1 en cas d’échec
|
||||
*/
|
||||
int mic_tcp_connect(int socket, mic_tcp_sock_addr addr)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
int mic_tcp_send (int mic_sock, char* mesg, int mesg_size)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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()
|
||||
*/
|
||||
int mic_tcp_recv (int socket, char* mesg, int max_mesg_size)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
int mic_tcp_close (int socket)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction : "); printf(__FUNCTION__); printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_put().
|
||||
*/
|
||||
void process_received_PDU(mic_tcp_pdu pdu, mic_tcp_sock_addr addr)
|
||||
{
|
||||
printf("[MIC-TCP] Appel de la fonction: "); printf(__FUNCTION__); printf("\n");
|
||||
}
|
40
tsock_texte
Executable file
40
tsock_texte
Executable 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
|
||||
|
63
tsock_video
Executable file
63
tsock_video
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/bin/bash
|
||||
|
||||
puits=false
|
||||
sourc=false
|
||||
protocol="tcp"
|
||||
port=`expr \`id -u\` % 3000 + 14578`
|
||||
|
||||
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:$port > /dev/null 2>&1 &
|
||||
|
||||
if [ "$protocol" = "mictcp" ]; then
|
||||
cd build
|
||||
./gateway -p -t $protocol $port &
|
||||
cd ..
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$sourc" = true ]; then
|
||||
|
||||
echo "Lancement de la source, protocol " $protocol
|
||||
cd build
|
||||
./gateway -s -t $protocol 127.0.0.1 $port &
|
||||
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
|
||||
|
1
video/video.bin
Symbolic link
1
video/video.bin
Symbolic link
|
@ -0,0 +1 @@
|
|||
video_starwars.bin
|
BIN
video/video_starwars.bin
Normal file
BIN
video/video_starwars.bin
Normal file
Binary file not shown.
BIN
video/video_wildlife.bin
Normal file
BIN
video/video_wildlife.bin
Normal file
Binary file not shown.
Loading…
Reference in a new issue