Travaux pratiques 4H
Pré-requis
Langage C (gcc) / debugger / cours de C
Cours Sockets, Wireshark /QCréator
Remarque , QtCréator , réaliser ce TP avec QtCréator
But
Utilisation des sockets pour faire communiquer des programmes.
Vos tp seront rédigés au format pdf envoyés en fin de séance sur l' email : snir2@workboot.fr
Réaliser un projet informatique
La qualité de la rédaction entre dans votre note , et les initiatives apportent beaucoup de points dans la notation.
Si il faut :
sudo apt-get install wireshark
Remarque ! Porter les codes dans Qtcréator.
Surveiller bien le contenu des structures !
Dans la partie cours prendre l'archive socket_udp.tar voir le cours
Est ce connecté ou non ? dans le sens des sockets (voir le cours !)
En local (127.0.0.1) tester et valider le code.
Utiliser le debugger pour bien décomposer ce qu'il se passe , et développer chaque structure.
Utiliser le debugger pour bien identifier les différentes opérations pour faire le parallèle avec le cours.
Prouver que ça n'est pas connecté ? apporter plusieurs arguments à votre réponse.
Pour le lancer il faut donner les droits root
du terminal:
sudo wireshark
Et choisir any (image ci dessus)
Et cliquer sur la nageoire du requin (bleu)
https://fr.wikipedia.org/wiki/Wireshark
Tracer en filtrant sur l'adresse locale
le filtre intéressant est ici (dans filter)
udp.port == 8888
Avec votre voisin croiser vos programmes , Serveur / Client
ip a ,pour obtenir vos adresses IP.
Utiliser Wireshark
Retrouver le Datagramme UDP avec wireshark
https://fr.wikipedia.org/wiki/User_Datagram_Protocol
Tester les codes pour réaliser une application de dialogue ,tchat .
Chacun un client et un serveur pour vous envoyer des messages.
Et tenir une conversation écrite.
Les serveurs sont connectés en permanence
Exécuter le serveur Afficheur 7 segments ( Aff7seg.tar.xz ) a décompresser et exécuter (rendre exécutable chmod +x )
Pour le piloter il faut connaître:
UDP
UDP_IP = "127.0.0.1"
UDP_PORT = 8585
Les commandes du serveur:
MESSAGE = "AFF7SEG;NB_DIGITS;6\n" #message CONFIG
Ce message permet d'avoir un afficheur avec 6 afficheurs .
MESSAGE = "AFF7SEG;DIGIT;0;255\n" #message VALEUR
Ce message allume tous les digits de l'afficheur en position 0 (le premier a gauche) ainsi que le point.
Explications sur les chaînes de commande.
Le message CONFIG , ou il y a un 6 actuellement , le 6 ici représente le nombre d'afficheur 7 segments que l'on veut.
Le message VALEUR permet de configurer l'afficheur .
Le message VALEUR, le champ ou il y a zéro on peut mettre d'autre valeurs entières permettant de cibler l'afficheur 7 segments que l'on veut modifier.
Le 0 éteint touts les segments. 255 allume tout les segments
A : bit 0 B : bit 1 C: bit 2 D: bit 3 E: bit 4 F: bit 5 G: bit 6
DP: bit 7
/*********************************
Simple udp client
Pour l'afficheur 7segments
**********************************/
#include<stdio.h> /* printf */
#include<string.h> /* memset */
#include<stdlib.h> /* exit(EXIT_SUCCESS);*/
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "127.0.0.1" /* adresse locale */
#define PORT 8585 /* The port on which to send data */
#define BUFLEN 512 /* Max length of buffer */
int main(void)
{
struct sockaddr_in si_other;
int s;
unsigned int slen=sizeof(si_other);
/* on declare ici la chaine pour faire 6 DIGITS */
char message[BUFLEN]="AFF7SEG;NB_DIGITS;6\n";
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
perror("pas de socket");
exit(EXIT_FAILURE);
}
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1)
{
perror("pas de sendto");
exit(EXIT_FAILURE);
}
close(s);
return EXIT_SUCCESS;
}
Pour ce travail nous pourrons utiliser les libs : string.h, stdio.h
strcpy()
sprintf(..) (comme un printf mais sur une chaîne de caractères)
man sprintf
...
int sprintf(char *str, const char *format, ...);
...
char * C_Config(int nb);
rappel : MESSAGE = "AFF7SEG;NB_DIGITS;6\n" #message CONFIG
(nb =6 ici)
char * C_Value(int nb, int pos );
rappel: MESSAGE = "AFF7SEG;DIGIT;0;255\n" #message VALEUR
(pos = 0 et nb=255 ici)
Pour envoyer la chaine avec la socket:
void Afficheur7s(char *chaine);
Pour regarder les trames passer, relever nos commandes.
exercice: ./annee
La valeur 2018 sur 4 Digits
Avec vos fonctions réalisées précédemment.
! Attention il faut coder ! (au plus simple et efficace)
!! Attention ÉCRIRE un code en C pour ! (on utilisera les fonctions)
exercice:
Sur un modèle a 2 afficheurs 7 segments (pour ne pas faire trop lourd), plus pour les plus courageux.
Lancer un chenillard qui fait tourner les segments externes des digits extérieurs
toutes les 200ms ça se déplace (ça tourne), comme ci-dessous.
Pour regarder les trames passer
Retrouver les Datagrammes et les chaînes envoyées (hacker)
https://fr.wikipedia.org/wiki/User_Datagram_Protocol
Pour piloter son afficheur et ou celui au tableau
Dans la partie cours prendre l'archive SOCKET_TCP.tar
Attention, vérifier dans le source comment les paramètres sont passés , et ce qu'il faut passer au programme (adresse IP et port ?)
C'est connecté?
En local (127.0.0.1) tester et valider le code.
Utiliser le debugger pour bien identifier les différentes opérations pour faire le parallèle avec le cours.
Prouvé que c' est connecté ? apporter un ou des arguments à votre réponse.
Tracer en filtrant sur l'adresse locale et le port
http://www.linux-france.org/prj/edu/archinet/systeme/ch01s03.html
Retrouver les adresses MAC des cartes réseau dans les trames de wireshark
rappel:
ip -c a
Avec votre voisin croiser vos programmes , Serveur / Client
ip -c a , pour obtenir vos adresse IP
https://memo-linux.com/ip-la-commande-linux-pour-gerer-son-interface-reseau/
Chacun un client et un serveur pour vous envoyer des messages.
A quoi sert la fonction htons et htonl
Écrire un petit programme qui affiche en hexdecimal le PORT a travers
%x permet l'affichage hexa
3-1 Tester avec un fork
Vu en cours avec Mr Besson
Tester l'exemple du cours :
SOCKET_FORK.TAR
Expliquer ... commenter ...
File transfert protocole:
Le serveur n'est pas mis par défaut car le ftp est non sécurisé donc de moins en moins populaire.
Le client FTP est mis par défaut.
ftp IPdelamachine
installer le serveur ftp
sudo apt install ftpd
Créer un compte sur votre machine (utilisateur)
Et vous y connecter a travers FTP.
Avec Wireshark retrouver le mot de passe .
on pourra juste se loguer.
Pourquoi est ce de moins en moins populaire?
sftp est mieux pourquoi?
Ecrire en TCP un petit serveur WEB, c'est un peu ce que fait apache mais mono utilisateur.
Ce genre de serveur peuvent servir sur des petits systèmes embarqués
On trouve des informations
https://rosettacode.org/wiki/Hello_world/Web_server
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
char response[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n\r\n"
"<!DOCTYPE html><html><head><title>Bye-bye baby bye-bye</title>"
"<style>body { background-color: #111 }"
"h1 { font-size:4cm; text-align: center; color: black;"
" text-shadow: 0 0 2mm red}</style></head>"
"<body><h1>Goodbye, world!</h1></body></html>\r\n";
int main()
{
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 8080;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
printf("got connection\n");
if (client_fd == -1) {
perror("Can't accept");
continue;
}
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
}
}
Observer avec wireshark
Sur le navigateur web la syntaxe est : ip : port
Ecrire un code pour obtenir une page WEB avec votre nom.