Public feed #892003

Stuff

public text v1 · immutable
Raw Edit
·published 2008-02-05 02:01 UTC
rendered paste body
/*
*	Programme:   client_base.c
*       Auteur:      Paul Girard Ph.D., DIM, UQAC
*       Date:        octobre 2000,  mod sept 2004, sept 2006, jan2008
*

// Modifier par: Francois-Luc Bergeron - BERF25118206
// UQAC
//Client FTP

*       But:    Exemple d'utilisation de socket TCP/IP 
*               pour un programme client dans un environnement
*		environnement Solaris 5.7 sur Sun permettant
*		l'envoi d'un message à un serveur et de recevoir
*		un accusé de réseption de ce dernier.  Un délai de
*	      	1 seconde permet de visualiser le transfert à l'écran.
*
*	Options de compilation et de link:          
*	===>	gcc client_base.c -lsocket -lnsl -o client_base
*
*       Exécution: 2 parametres formels: nom du serveur et no de port du serveur
*	=========>  client_base nom_serveur #port
*		ex. client_base "sunens.uqac.ca" 5001
*
*
*       Fichiers a inclure
*/
#include <errno.h>         
#include <string.h>        
#include <sys/types.h>     
#include <sys/socket.h>    
#include <netinet/in.h>
#include <netdb.h>         
#include <sys/time.h>      
#include <stdio.h>         

/*	Les fonctions suivantes seront utilisées
*       pour la creation d'un socket, la recherche de l'adresse
*	reseau du serveur, la demande de connection au socket du serveur,
*	l'envoi et la reception de message et la
*	fermeture du socket.
*               		socket, gethostbyname, connect, 
*               		read, write, close.
*/

#define DATA "Paquet bidon du client transmis au serveur par TCP"
#define NAK "nom de fichier incorrecte.(NAK)\n"
#define ACK "Fichier accepté.(ACK)\n" // le serveur accepte le nom du fichier

main(argc,argv)
        int argc;
        char *argv[];			/* argv[0] pointe sur le nom du prog
        				   argv[1] pointe sur le nom du serveur
        				   argv[2] pointe sur le numero du port tcp*/
{
        int conn;		/* descripteur de socket  */
        struct sockaddr_in server1; 	/*structure utilisee pour
					assigner un nom a un socket
					selon le format internet */
        size_t length;			/* #octets de la structure sockadr_in */
        struct hostent *hp,*gethostbyname(); /* structure pour associer
					le nom de l'hote et son adresse
					d'apres le format internet */
	struct hostent hpstruct; /* structure accédant la partie adresse du serveur */
        char buf[80];		/* tampon pour la reception d'un message */ 
        int rval;		/* code de statut pour le read */
	int n, i;		/* compteurs temporaires */
	double noctets=0;
/*
*	1. Validation des parametres sur la ligne de commande
*/
	if (argc != 3)
	{
		printf("Appelez le programme ainsi: client_base nom_serveur no_port\n");
		exit(1);
	}
/*
*	2. Creation d'un socket en mode TCP (sock_stream) et en suivant
*	les regles d'internet (AF_INET) pour le format d'adresse
*	avant de pouvoir transmettre 
*/
        conn = socket(AF_INET, SOCK_STREAM, 0);
        if (conn < 0) 
	{
                perror("erreur de creation du socket conn");
                exit(1);
        }
/*
*	3. Obtenir un pointeur a la structure d'adresse reseau du
*	serveur specifie.  Le nom du serveur est pris
*	comme parametre formel sur la ligne de commande (argv[1]):
		ex.  "sunens.uqac.ca"
*/
        server1.sin_family = AF_INET;	/* format internet */
        hp = gethostbyname(argv[1]);	/* pointeur de la structure
					du serveur en ecoute sur le
					port pointe par arg[1] */
        if (hp == 0)
	{
                fprintf(stderr, "%s: hote inconnu ===>", argv[1]);
                exit(2);
        }
	hpstruct = *hp;	/*  sauvegarder les donnees hostent */

/*
*	4. Remplir la partie adresse remote pour la structure du nouveau socket
*/
	server1.sin_family = hpstruct.h_addrtype;
	server1.sin_port = htons(atoi(argv[2]));  /* #port char => #port entier interne
						     #port entier format reseau */
	server1.sin_addr = * ((struct in_addr *) hpstruct.h_addr);

/* 	5. Connecter le socket local (conn) au socket du serveur specifie
*	par l'adresse de sa structure (server1)
*/
	hrtime_t debut,fin;
	double delais;
	
	debut=gethrtime()/1000;
	if (connect(conn, (struct sockaddr *)&server1, sizeof(server1)) < 0)
	{
                perror("erreur de connexion");
                exit(1);
        }

		
/*	
*	5.1 saisie du nom de fichier et vérification de ce fichier, coté client.
*
*/	
FILE *fptr;
char ligne[80];
char filename_local[80];
char filename_distant[80];



puts("nom du fichier a transmettre ?");
gets(filename_local);
if((fptr = fopen(filename_local, "r"))==NULL)
{
	perror("erreur d'ouverture de fichier");
	exit(0);
}

puts("nom du fichier a enregistrer ?");
gets(filename_distant);


/*	
*	5.2 envoi du nom de fichier, attende de validation du serveur.
*
*/	
                if(write(conn, filename_distant, sizeof (filename_distant)) < 0)
                        perror("erreur dans l'emission d'un message");
                else { 
				/*  initialiser le tampon pour la reception */
                        if ((rval = read(conn, buf, 80)) < 0) 
                           perror("erreur de lecture du message");// si erreur
						   
                        if (rval == 0)					//si fin de message
                           printf("Fin de la connection\n");
						   
						buf[rval]='\0';	
						if (0== (strcmp( buf, NAK )))
						{
							perror("mauvais nom de fichier123");//if NAK
							exit(0);
						}
							else
							{
							//else ACK.. alors envoi du fichier ligne par ligne
							//buf[rval]='\0';	
							printf(buf);

							
/*	6  envoi du fichier, ligne par ligne.
*	
*
*/													
							
							do{
								fgets(ligne,80,fptr);								
								if((noctets+=write(conn, ligne, sizeof (ligne))) < 0)
								perror("erreur dans l'emission du fichier");				

							}while(!feof(fptr));
							fclose(fptr);
						//printf("fermeture fichier\n");
							}	
					 
					 }




        close(conn);
		fin= gethrtime()/1000;
		delais=(double)(fin-debut)/1000;
	
	printf("Nombre d'octets envoyés: %9.2f \n",noctets);
	printf("Debit = %7.2f Ko/sec \t\tTemps de transfert TCP = %9.3f msec\n", (double)(noctets*1000)/(1024*delais), delais);
	puts("Fin du programme client");
    exit(0);	/* fin du programme client */
}