SlideShare a Scribd company logo
1 of 16
Download to read offline
Reti di calcolatori - Fabiano Dalla Piazza
===================================================================================
===============================================================
/*SERVER*/
/*TESINA SCRITTA IN C PER RETI DI CALCOLATORI A CURA DI FABIANO DALLA PIAZZA*/
/*UNIVERSITA' DEGLI STUDI DI TRIESTE*/
/*QUESTO FILE E' COMPOSTO DI UN PROGRAMMA PRINCIPALE(main),UNA PROCEDURA(ls) E*/
/*TRE SOTTOPROGRAMMI(invia,ricevi E fai).IL MAIN CREA UN SOCKET,EFFETTUA IL BINDING*/
/*TRA SOCKET E INDIRIZZO DELLA MACCHINA LOCALE,OTTIENE IL NOME DEL SOCKET ED
ESEGUE*/
/*IL LISTENING PER COMUNICARE LA DISPONIBILTA' AD ACCETTARE FINO A 8 CONNESSIONI.*/
/*POI,SE RIESCE A IMPOSTARE LA MODALITA' PASSIVA,ELABORA LE RICHIESTE DEL CLIENT*/
/*AVVALENDOSI DEL SOTTOPROGRAMMA FAI E CHIUDE LA CONNESSIONE TCP SIA IN INPUT,SIA IN
OUTPUT.*/
/*IL SOTTOPROGRAMMA FAI PRENDE LA PRIMA RICHIESTA IN CODA E CREA UN ALTRO SOCKET.*/
/*LEGGE I PARAMETRI E IL COMANDO INVIATOGLI DAL CLIENT TRAMITE IL SOTTOPROGRAMMA
RICEVI.*/
/*CONTROLLA LE DIRETTIVE IMPARTITE DAL CLIENT E,SE DEVE USCIRE O TESTARE,CHIAMA IL*/
/*SOTTOPROGRAMMA INVIO PER SEGNALARE IL NUMERO DI RIGHE CHE SI TRASMETTERANNO NEL
CANALE,*/
/*MENTRE SE DEVE ESEGUIRE IL COMANDO LS CHIAMA LA PROCEDURA LS.INFINE CHIUDE IL
SOCKET.*/
/*LA PROCEDURA LS SI INCARICA DI APRIRE LA DIRECTORY,COMUNICARE AL CLIENT L'ARRIVO*/
/*DI RIGHE CON IL SOTTOPROGRAMMA INVIA,ESEGUIRE UN CICLO DI LETTURA,CHIUDERE LA*/
/*DIRECTORY E SEGNALARE IL FINE FLUSSO.*/
/*IL SOTTOPROGRAMMA INVIA FRAMMENTA LA STRINGA RICEVUTA IN FRAMES E LI INVIA AL
SOCKET,MENTRE*/
/*IL SOTTOPROGRAMMA RICEVI LEGGE LA STRINGA RICEVUTA E LA IMMETTE NEL BUFFER.*/
/*direttive di definizione al preprocessore*/
/*portad è la porta per default,buffersiz è la capacità di memoria residente nel buffer*/
/*poi ci sono le varie librerie*/
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#ifndef unix
#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
1agina p
Reti di calcolatori - Fabiano Dalla Piazza
#if defined __CYGWIN__
#include <io.h>
#else
#include <sys/io.h>
#endif
#define portad 5193
#define buffersiz 500
/*prototipi dei sottoprogrammi e procedure varie*/
int invia(int sid,char *str);
int ricevi(int sid,char *str,int siz);
int fai(int soce);
void ls(int scke,char *wher);
/*programma principale*/
int main(int argc,char *argv[]){
int skt,lun,por,warn,ext;
struct sockaddr_in skaddr;
ext=0;
warn=1;
/*la porta é quella di default*/
por=portad;
/*confronto i parametri in ingresso*/
if(argc > 1){
/*se é l'help,visualizzo l'aiuto*/
if(strcmp(argv[1],"--help") == 0)
{
printf("server in uso n");
printf("server la porta del socket diviene quella di default (%i)n",portad);
printf("server[sys] la porta del socket è distribuita dal sistema operativon");
printf("server --help aiutonn");
ext=1;
}
/*se la stringa é sys,il numero di porta é assegnato dal sistema operativo*/
else if(strcmp(argv[1],"sys") == 0)
por=0;
else
{
printf("visualizzare l'aiuton");
2agina p
Reti di calcolatori - Fabiano Dalla Piazza
ext=1;
}
}
/*se parametri ok allora*/
if(!ext)
{
/*inizializzazione per WIN32*/
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101,&wsaData);
#endif
/*creazione del socket di famiglia PF_INET,con servizio SOCK_STREAM,tipo TCP(0)*/
/*si crea un protocollo per ciascuna connessione*/
/*se riesco a creare il socket,configuro il suo indirizzo*/
if((skt=socket(PF_INET,SOCK_STREAM,0)) >= 0 && (!ext)){
/*la famiglia dell'indirizzo é AF_INET*/
skaddr.sin_family=AF_INET;
/*l'indirizzo IP locale é INADDR_ANY,uno qualsiasi degli indirizzi IP*/
/*con cui la macchina viene riconosciuta in rete*/
skaddr.sin_addr.s_addr=INADDR_ANY;
/*viene assegnata la porta*/
skaddr.sin_port=htons(por);
/*eseguo il binding(assegnazione nome) tra socket e indirizzo della macchina locale*/
if(bind(skt,(struct sockaddr *) &skaddr,sizeof(skaddr)) >= 0){
/*binding riuscito:allora trovo il numero di porta e lo visualizzo*/
lun=sizeof(skaddr);
/*se ottengo il nome del socket*/
if(getsockname(skt,(struct sockaddr *) &skaddr,&lun) >= 0){
printf("server(locale):il numero della porta e' %dn",ntohs(skaddr.sin_port));
/*il server comunica che é disposto ad accettare connessioni accodate*/
/*fino a un massimo di 8 richieste(numero da
me fissato)*/
if(listen(skt,8) >= 0){
/*se riesco a far lavorare il socket in modalità passiva*/
3agina p
Reti di calcolatori - Fabiano Dalla Piazza
if((warn=fai(skt)) != 0)
printf("server(locale):errore di elaborazionen");
/*chiusura della connessione TCP di client e
server(direzione 2)*/
/*se la direzione é 0 chiude solo il server*/
/*se é 1 chiude solo il client*/
shutdown(skt,2);
printf("server(locale):fine operazioni come richiesto dal clientn");
}
else
printf("server(locale):errore nel listenn");
}
else
printf("server(locale):errore nella ricerca nome socketn");
}
else
printf("server(locale):errore nel binding tra socket e macchinan");
}
else
printf("server(locale):errore nella creazione del socketn");
}
return warn;
}
/*implementazione del sottoprogramma fai*/
/*il sottoprogramma esegue le direttive impartite dal client*/
int fai(int soce){
int sonum,abc,k,luind,numerop,erro,ext;
struct sockaddr vie;
char buffe[buffersiz],ord[buffersiz],prmt[3][buffersiz];/*matrice prmt*/
/*con massimo
tre parametri*/
/*ciclo di processo delle richieste del client*/
abc=0;
ext=0;
4agina p
Reti di calcolatori - Fabiano Dalla Piazza
erro=0;
for(;!erro && !ext;){
/*fisso una lunghezza di indirizzo pari a 16*/
luind=16;
/*la accept prende la prima richiesta in coda,crea un altro socket(sonum),se */
/*non ci sono richieste in sospeso,si blocca in attesa*/
if((sonum=accept(soce,&vie,&luind)) >= 0)
{
printf("server(locale):c' é una connessione (n.%u),elaboro n",abc);
/*leggo quanti parametri invia il client*/
ricevi(sonum,ord,buffersiz);
/*converto in intero e visualizzo numero parametri*/
numerop=atoi(ord);
printf("numero parametri= %un",numerop);
/*leggo il comando del client*/
ricevi(sonum,ord,buffersiz);
/*controllo del comando del client*/
if(strcmp(ord,"ls") == 0 || strcmp(ord,"exit") == 0 || strcmp(ord,"test") == 0){
/*comando valido,allora considero il comando ricevuto*/
if(strcmp(ord,"exit") == 0){
/*richiesta di fine elaborazione*/
ext=1;
/*invio il numero di righe che si trasmetteranno nel canale*/
invia(sonum,"2");
invia(sonum,"sono il server:fine elaborazioni ");
}
else{
/*se il comando non é exit,azzero i vecchi parametri*/
/*e leggo gli eventuali parametri rimanenti*/
/*ciclo fino a tre perché é l numero massimo di parametri
che consento*/
for(k=0;k < 3;k++)
prmt[k][0]='0';
for(k=0;k < numerop-1;k++){
5agina p
Reti di calcolatori - Fabiano Dalla Piazza
ricevi(sonum,buffe,buffersiz);
if(k < 3)
/*salvo il comando,(3) é sempre il max numero parametri*/
strcpy(prmt[k],buffe);
}
if(strcmp(ord,"test") == 0){
/*se il comando é test*/
invia(sonum,"2");
invia(sonum,"sono il server:eseguo il test ");
}
else{
/*caso in cui il comando é ls:il client cercherà
nella directory*/
/*se la stringa é zero,non viene specificata una
directory*/
/*su cui eseguire il listing*/
if(strcmp(prmt[0],"") == 0)
ls(sonum,"");
else
ls(sonum,"r");
}
}
}
else{
/*comando non valido*/
/*invio il numero di righe che si trasmetteranno nel canale*/
invia(sonum,"2");
invia(sonum,"comando non valido ");
/*tolgo eventuali parametri passati nel canale*/
for(k=0;k < numerop-1;k++)
ricevi(sonum,buffe,buffersiz);
}
printf("server(locale):connessione elaborata (n.%u)n",abc);
/*chiusura del socket di comunicazione*/
closesocket(sock);
abc++;
}
else
erro= 1;
6agina p
Reti di calcolatori - Fabiano Dalla Piazza
}
return erro;
}
/*procedura ls*/
void ls(int scke,char *wher){
int errore;
DIR *direc=NULL;
struct dirent *afd=NULL;
char nmfl[24];/*massimo numero caratteri del nome file fissato a 24*/
errore=1;
/*se non viene specificata una directory*/
if(*wher == '0')
/*allora apro la directory locale del server*/
direc=opendir(".");
/*altrimenti apro quella specificata per il listing*/
else
direc=opendir(wher);
/*se la directory non é vuota*/
if(direc != NULL){
/*avviso il client dell'arrivo di un numero imprecisato di righe*/
invia(scke,"0");
/*ciclo di lettura dei files*/
while(!errore && (afd=readdir(direc))!=NULL){
/*terminatore di stringa*/
#ifndef _DIRENT_HAVE_D_NAMLEN
strncpy(nmfl,afd->d_name,afd->d_namlen+1);
#else
strcpy(nmfl,afd->d_name);
#endif
/*invio stringa al client*/
invia(scke,nmfl);
}
/*chiudo la directory*/
closedir(direc);
/*avverto il client del termine flusso*/
if(!errore)
7agina p
Reti di calcolatori - Fabiano Dalla Piazza
invia(scke,"FINEFLUSSO");
}
else{
/*errore nel parametro,avvertimento al client*/
invia(sd,"2");
invia(sd,"errore nel parametro ls");
}
}
/*il sottoprogramma invia manda pezzi di stringa al socket*/
/*in base ai dati forniti,e aggiunge un terminatore di fine stringa newline*/
int invia(int sid,char *str){
int dim,scr,siz,a,wri,exi;
char newl[2];
/*trovo la lunghezza stringa e azzero i parametri contatore e uscita*/
siz=dim=strlen(str);
a=0;
exi=0;
/*finché c'è stringa e non esco,invio un suo pezzo,*/
/*ricordo dove sono arrivato e scalo dal contatore*/
while(siz > 0 && (!exi)){
/*invio vero e proprio*/
wri=send(sid,str+a,siz,0);
if(wri > 0){
a+=wri;
siz-=wri;
}
/*errore in trasmissione:esco*/
else
exi=1;
}
/*lunghezza stringa rimanente*/
scr=(strlen(str)-siz);
/*aggiungo il carattere newline come terminatore di fine stringa*/
strcpy(newl,"n");
if(dim > 0 && str[dim-1]!='n'){
siz=strlen(newl);
a=0;
8agina p
Reti di calcolatori - Fabiano Dalla Piazza
exi=0;
while(siz > 0 && (!exi)){
wri=send(sid,newl+a,siz,0);
/*errore,esco*/
if(wri <= 0)
exi=1;
else{
a+=wri;
siz-=wri;
}
}
scr=(strlen(newl)-siz);
}
/*restiruisco la lunghezza stringa rimanente*/
return scr;
}
/*il sottoprogramma ricevi legge un byte alla volta la stringa del socket sid,*/
/*la inserisce nel buffer,terminandola con null(come negli esempi),infine*/
/*restituisce il numero di caratteri della stringa*/
int ricevi(int sid,char *str,int siz){
int a,rea,exi;
char c;
a=0;
exi=0;
/*finché non devo uscire,eseguo un ciclo di lettura dal socket*/
/*un carattere alla volta*/
for(;!exi;){
rea=recv(sid,&c,1,0);
/*caso standard:c'é il carattere e non é newline*/
if(rea == 1 && a < siz && c!='n'){
*(str+a)=c;
a++;
}
/*se non ho carattere o esso é newline,esco*/
else if((rea == 0)||(rea == 1 && c == 'n')){
*(str+a)='0';
rea=a+1;
exi=1;
}
/*in caso di errore,esco*/
else{
*(str+a)='0';
rea=-1;
9agina p
Reti di calcolatori - Fabiano Dalla Piazza
exi=1;
}
}
/*restituisco il numero di caratteri eccetto il terminatore*/
return rea;
}
===================================================================================
===============================================================
/*CLIENT*/
/*TESINA SCRITTA IN C PER RETI DI CALCOLATORI A CURA DI FABIANO DALLA PIAZZA*/
/*UNIVERSITA' DEGLI STUDI DI TRIESTE*/
/*IL FILE E' COMPOSTO DAL PROGRAMMA PRINCIPALE(main) E DUE SOTTOPROGRAMMI(invia e
ricevi).*/
/*IL MAIN CREA UN SOCKET IP ORIENTATO ALLA CONNESSIONE TCP DI DOMINIO
INTERNET,GUARDA NELLA DNS E*/
/*OTTIENE IL NOME DELL'HOST SERVER.EFFETTUA LA CONNESSIONE,USA IL SOTTOPROGRAMMA
INVIA PER MANDARE*/
/*AL SOCKET I PARAMETRI E IL COMANDO DA ESEGUIRE.USA IL SOTTOPROGRAMMA RICEVI PER
SAPERE*/
/*QUANTI PARAMETRI RICEVERA' DALL'UTENTE,E IN BASE A CIO' SA QUANTE RIGHE SUCCESSIVE
ATTENDERSI,*/
/*LE LEGGE CON IL SOTTOPROGRAMMA RICEVI,EVENTUALMENTE RICEVENDO UNA STRINGA DI
"FINEFLUSSO"*/
/*QUALORA IL NUMERO DI RIGHE NON SIA NOTO A PRIORI.INFINE CHIUDE IL SOCKET.*/
/*IL SOTTOPROGRAMMA INVIA FRAMMENTA LA STRINGA RICEVUTA IN FRAMES E LI INVIA AL
SOCKET,MENTRE*/
/*IL SOTTOPROGRAMMA RICEVI LEGGE LA STRINGA RICEVUTA E LA IMMETTE NEL BUFFER.*/
/*direttive di definizione al preprocessore*/
/*portad è la porta per default,buffersiz è la capacità di memoria residente nel buffer*/
/*poi ci sono le varie librerie*/
#include <stdio.h>
#include <string.h>
#ifndef unix
#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
10agina p
Reti di calcolatori - Fabiano Dalla Piazza
#include <netdb.h>
#endif
#define portad 5193
#define buffersiz 500
/*prototipi delle funzioni di lettura e spedizione dati*/
/*sid é l'astrazione per la comunicazione di rete*/
int invia(int sid,char *str);
int ricevi(int sid,char *str,int siz);
/*corpo del programma*/
int main(int argc,char *argv[]){
int j,sock,numerop,uscita;
struct hostent *hpt;
struct sockaddr_in skaddr;
char buff[buffersiz];
/*inizializzazione per WIN32*/
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101,&wsaData);
#endif
if(argc < 4){
/*se non ho parametri a sufficienza*/
printf("client n");
printf("client <host_server> <porta> <exit> termina la connessionen");
printf("client <host_server> <porta> <ls> [file [">" file2]] directory remotan");
printf("client <host_server> <porta> <test> test della connessionen");
printf("nse la <porta> == default (allora la porta diviene quella di default
(%i)nn",portad);
}
else{
/*se ho parametri sufficienti*/
uscita=0;
/*creo un socket IP orientato alla connessione TCP*/
/*di dominio Internet PF_INET e tipo,protocollo SOCK_STREAM,0*/
if((sock=socket(PF_INET,SOCK_STREAM,0)) >= 0 && (!uscita)){
/*se creo il socket e non devo uscire*/
if((hpt= gethostbyname(argv[1])) != 0){
11agina p
Reti di calcolatori - Fabiano Dalla Piazza
/*con la funzione gethostbyname ottengo il nome dell'host:guarda*/
/*nella DNS e ritorna il puntatore *hpt alla struttura*/
/*configurazione della struttura con famiglia di indirizzi AF_INET*/
/*per indirizzi TCP/IP,e mappa il nome di protocollo*/
/*di trasporto al numero di protocollo*/
skaddr.sin_family= AF_INET;
memcpy(&skaddr.sin_addr.s_addr,hpt->h_addr,hpt->h_length);
if(strcmp(argv[2],"def") == 0)
/*confronto le due stringhe:se sono uguali uso la porta di default*/
skaddr.sin_port=htons(portad);
else
/*altrimenti se le due stringhe non sono uguali non uso*/
/*la porta di default*/
skaddr.sin_port=htons(atoi(argv[2]));
/*connetto il server con connect*/
if(connect(sock,(struct sockaddr *) &skaddr,sizeof(skaddr)) >= 0){
/*invio il numero dei parametri,poi primo
parametro,secondo parametro,etc..*/ /*sprintf invia l'output nel
buffer*/
sprintf(buff,"%i",argc - 3);
/*vengono inviati i parametri forniti dall'utente*/
invia(sock,buff);
/*viene inviato il comando*/
invia(sock,argv[3]);
/*se esistono altri parametri,invio anche quelli*/
for(j=4;j < argc;j++)
invia(sock,argv[j]);
/*leggo un byte alla volta dalla prima stringa del socket
sock*/
/*quanti parametri riceverò e la inserisco nel buffer*/
ricevi(sock,buff,buffersiz);
/*converto in intero*/
numerop=atoi(buff);
/*se il numero di parametri è nullo,allora il*/
/*numero righe é imprecisato*/
12agina p
Reti di calcolatori - Fabiano Dalla Piazza
if(numerop == 0){
/*risposta del server*/
printf("client:la risposta dal server é:n");
uscita=0;
/*se non esco*/
for(;!uscita;){
/*leggo un byte alla volta la stringa
del socket sock*/
/*e la inserisco nel buffer*/
ricevi(sock,buff,buffersiz);
/*se la stringa ricevuta è
FINEFLUSSO esco*/
/*dal ciclo:non ci sono più stringhe
da leggere*/
if(strcmp(buff,"FINEFLUSSO")==0)
uscita= 1;
else
printf("%sn",buff);
}
}
else{
/*se il numero di righe non è zero*/
/*ci saranno numero di parametri-1 riga*/
printf("client:la risposta dal server é:n",numerop-1);
/*cicla numero righe-1 volte*/
for (j=0;j < numerop-1;j++){
/*leggo un byte alla volta la stringa
del socket sock*/
/*e la inserisco nel buffer*/
ricevi(sock,buff,buffersiz);
/*visualizzo*/
printf("%sn",buff);
}
}
}
13agina p
Reti di calcolatori - Fabiano Dalla Piazza
else
/*se la connessione non riesce*/
printf("client:connessione col server non riuscita!n");
}
else
/*host sconosciuto o quantomeno indeterminabile*/
printf("client:errore hostn");
/*chiusura del socket di comunicazione*/
closesocket(sock);
}
else
printf("client:creazione socket non valida!n");
}
return 0;
}
/*il sottoprogramma invia manda pezzi di stringa al socket*/
/*in base ai dati forniti,e aggiunge un terminatore di fine stringa newline*/
int invia(int sid,char *str){
int dim,scr,siz,a,wri,exi;
char newl[2];
/*trovo la lunghezza stringa e azzero i parametri contatore e uscita*/
siz=dim=strlen(str);
a=0;
exi=0;
/*finché c'è stringa e non esco,invio un suo pezzo,*/
/*ricordo dove sono arrivato e scalo dal contatore*/
while(siz > 0 && (!exi)){
/*invio vero e proprio*/
wri=send(sid,str+a,siz,0);
if(wri > 0){
a+=wri;
siz-=wri;
}
/*errore in trasmissione:esco*/
else
exi=1;
14agina p
Reti di calcolatori - Fabiano Dalla Piazza
}
/*lunghezza stringa rimanente*/
scr=(strlen(str)-siz);
/*aggiungo il carattere newline come terminatore di fine stringa*/
strcpy(newl,"n");
if(dim > 0 && str[dim-1]!='n'){
siz=strlen(newl);
a=0;
exi=0;
while(siz > 0 && (!exi)){
wri=send(sid,newl+a,siz,0);
/*errore,esco*/
if(wri <= 0)
exi=1;
else{
a+=wri;
siz-=wri;
}
}
scr=(strlen(newl)-siz);
}
/*restiruisco la lunghezza stringa rimanente*/
return scr;
}
/*il sottoprogramma ricevi legge un byte alla volta la stringa del socket sid,*/
/*la inserisce nel buffer,terminandola con null(come negli esempi),infine*/
/*restituisce il numero di caratteri della stringa*/
int ricevi(int sid,char *str,int siz){
int a,rea,exi;
char c;
a=0;
exi=0;
/*finché non devo uscire,eseguo un ciclo di lettura dal socket*/
/*un carattere alla volta*/
for(;!exi;){
rea=recv(sid,&c,1,0);
/*caso standard:c'é il carattere e non é newline*/
if(rea == 1 && a < siz && c!='n'){
*(str+a)=c;
a++;
}
15agina p
Reti di calcolatori - Fabiano Dalla Piazza
/*se non ho carattere o esso é newline,esco*/
else if((rea == 0)||(rea == 1 && c == 'n')){
*(str+a)='0';
rea=a+1;
exi=1;
}
/*in caso di errore,esco*/
else{
*(str+a)='0';
rea=-1;
exi=1;
}
}
/*restituisco il numero di caratteri eccetto il terminatore*/
return rea;
}
===================================================================================
===============================================================
16agina p

More Related Content

Viewers also liked

Questionario docenti riepilogo istituto 2013fatto
Questionario docenti riepilogo istituto 2013fattoQuestionario docenti riepilogo istituto 2013fatto
Questionario docenti riepilogo istituto 2013fattoicbariano
 
La relazione sul giorno del ricordo
La relazione sul giorno del ricordoLa relazione sul giorno del ricordo
La relazione sul giorno del ricordoMattia Gandini
 
Fiori per sette_giorni
Fiori per sette_giorniFiori per sette_giorni
Fiori per sette_giorniBetty63
 
Parcheggi Rosa
Parcheggi RosaParcheggi Rosa
Parcheggi RosaNPCampo
 

Viewers also liked (8)

Famiglia Povera
Famiglia PoveraFamiglia Povera
Famiglia Povera
 
Prova
ProvaProva
Prova
 
Smwmilan14_editing
Smwmilan14_editingSmwmilan14_editing
Smwmilan14_editing
 
Questionario docenti riepilogo istituto 2013fatto
Questionario docenti riepilogo istituto 2013fattoQuestionario docenti riepilogo istituto 2013fatto
Questionario docenti riepilogo istituto 2013fatto
 
La relazione sul giorno del ricordo
La relazione sul giorno del ricordoLa relazione sul giorno del ricordo
La relazione sul giorno del ricordo
 
Fiori per sette_giorni
Fiori per sette_giorniFiori per sette_giorni
Fiori per sette_giorni
 
Parcheggi Rosa
Parcheggi RosaParcheggi Rosa
Parcheggi Rosa
 
Kpi
KpiKpi
Kpi
 

Similar to Reti di calcolatori Fabiano dalla piazza

Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacyTommaso Torti
 
SplunkLive! Milan 2015 - UNIBO
SplunkLive! Milan 2015 - UNIBOSplunkLive! Milan 2015 - UNIBO
SplunkLive! Milan 2015 - UNIBOSplunk
 
Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Diego Drigani
 
Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Steve Maraspin
 
Reactive programming con RxJS
Reactive programming con RxJSReactive programming con RxJS
Reactive programming con RxJSNucleode Srl
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerMassimiliano Arione
 
breve introduzione a node.js
breve introduzione a node.jsbreve introduzione a node.js
breve introduzione a node.jsnetmeansnet
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...UltraUploader
 
Ridirezionamento di I/O con Bash: un breve approfondimento
Ridirezionamento di I/O con Bash: un breve approfondimentoRidirezionamento di I/O con Bash: un breve approfondimento
Ridirezionamento di I/O con Bash: un breve approfondimentoBabel
 
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSL
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSLCorso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSL
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSLMassimiliano Masi
 

Similar to Reti di calcolatori Fabiano dalla piazza (20)

Javascript
JavascriptJavascript
Javascript
 
Dominare il codice legacy
Dominare il codice legacyDominare il codice legacy
Dominare il codice legacy
 
Php mysql3
Php mysql3Php mysql3
Php mysql3
 
SplunkLive! Milan 2015 - UNIBO
SplunkLive! Milan 2015 - UNIBOSplunkLive! Milan 2015 - UNIBO
SplunkLive! Milan 2015 - UNIBO
 
Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2Levate l'ancora! Rotte senza problemi con ZF2
Levate l'ancora! Rotte senza problemi con ZF2
 
Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1
 
Reactive programming con RxJS
Reactive programming con RxJSReactive programming con RxJS
Reactive programming con RxJS
 
08 mapreduce
08   mapreduce08   mapreduce
08 mapreduce
 
Gestione delle dipendenze con Composer
Gestione delle dipendenze con ComposerGestione delle dipendenze con Composer
Gestione delle dipendenze con Composer
 
Battaglia Navale
Battaglia NavaleBattaglia Navale
Battaglia Navale
 
Devianze
DevianzeDevianze
Devianze
 
Java lezione 10
Java lezione 10Java lezione 10
Java lezione 10
 
breve introduzione a node.js
breve introduzione a node.jsbreve introduzione a node.js
breve introduzione a node.js
 
Lezione 3: Connessioni TCP
Lezione 3: Connessioni TCPLezione 3: Connessioni TCP
Lezione 3: Connessioni TCP
 
Dal C a Java (2/3)
Dal C a Java (2/3)Dal C a Java (2/3)
Dal C a Java (2/3)
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
 
Ridirezionamento di I/O con Bash: un breve approfondimento
Ridirezionamento di I/O con Bash: un breve approfondimentoRidirezionamento di I/O con Bash: un breve approfondimento
Ridirezionamento di I/O con Bash: un breve approfondimento
 
Java lezione 14
Java lezione 14Java lezione 14
Java lezione 14
 
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSL
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSLCorso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSL
Corso IFTS CyberSecurity Expert - Creazione di una CA con OpenSSL
 
Idp, passo dopo passo!
Idp, passo dopo passo!Idp, passo dopo passo!
Idp, passo dopo passo!
 

Reti di calcolatori Fabiano dalla piazza

  • 1. Reti di calcolatori - Fabiano Dalla Piazza =================================================================================== =============================================================== /*SERVER*/ /*TESINA SCRITTA IN C PER RETI DI CALCOLATORI A CURA DI FABIANO DALLA PIAZZA*/ /*UNIVERSITA' DEGLI STUDI DI TRIESTE*/ /*QUESTO FILE E' COMPOSTO DI UN PROGRAMMA PRINCIPALE(main),UNA PROCEDURA(ls) E*/ /*TRE SOTTOPROGRAMMI(invia,ricevi E fai).IL MAIN CREA UN SOCKET,EFFETTUA IL BINDING*/ /*TRA SOCKET E INDIRIZZO DELLA MACCHINA LOCALE,OTTIENE IL NOME DEL SOCKET ED ESEGUE*/ /*IL LISTENING PER COMUNICARE LA DISPONIBILTA' AD ACCETTARE FINO A 8 CONNESSIONI.*/ /*POI,SE RIESCE A IMPOSTARE LA MODALITA' PASSIVA,ELABORA LE RICHIESTE DEL CLIENT*/ /*AVVALENDOSI DEL SOTTOPROGRAMMA FAI E CHIUDE LA CONNESSIONE TCP SIA IN INPUT,SIA IN OUTPUT.*/ /*IL SOTTOPROGRAMMA FAI PRENDE LA PRIMA RICHIESTA IN CODA E CREA UN ALTRO SOCKET.*/ /*LEGGE I PARAMETRI E IL COMANDO INVIATOGLI DAL CLIENT TRAMITE IL SOTTOPROGRAMMA RICEVI.*/ /*CONTROLLA LE DIRETTIVE IMPARTITE DAL CLIENT E,SE DEVE USCIRE O TESTARE,CHIAMA IL*/ /*SOTTOPROGRAMMA INVIO PER SEGNALARE IL NUMERO DI RIGHE CHE SI TRASMETTERANNO NEL CANALE,*/ /*MENTRE SE DEVE ESEGUIRE IL COMANDO LS CHIAMA LA PROCEDURA LS.INFINE CHIUDE IL SOCKET.*/ /*LA PROCEDURA LS SI INCARICA DI APRIRE LA DIRECTORY,COMUNICARE AL CLIENT L'ARRIVO*/ /*DI RIGHE CON IL SOTTOPROGRAMMA INVIA,ESEGUIRE UN CICLO DI LETTURA,CHIUDERE LA*/ /*DIRECTORY E SEGNALARE IL FINE FLUSSO.*/ /*IL SOTTOPROGRAMMA INVIA FRAMMENTA LA STRINGA RICEVUTA IN FRAMES E LI INVIA AL SOCKET,MENTRE*/ /*IL SOTTOPROGRAMMA RICEVI LEGGE LA STRINGA RICEVUTA E LA IMMETTE NEL BUFFER.*/ /*direttive di definizione al preprocessore*/ /*portad è la porta per default,buffersiz è la capacità di memoria residente nel buffer*/ /*poi ci sono le varie librerie*/ #include <stdio.h> #include <string.h> #include <dirent.h> #ifndef unix #define WIN32 #include <windows.h> #include <winsock.h> #else #define closesocket close #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <netdb.h> #endif 1agina p
  • 2. Reti di calcolatori - Fabiano Dalla Piazza #if defined __CYGWIN__ #include <io.h> #else #include <sys/io.h> #endif #define portad 5193 #define buffersiz 500 /*prototipi dei sottoprogrammi e procedure varie*/ int invia(int sid,char *str); int ricevi(int sid,char *str,int siz); int fai(int soce); void ls(int scke,char *wher); /*programma principale*/ int main(int argc,char *argv[]){ int skt,lun,por,warn,ext; struct sockaddr_in skaddr; ext=0; warn=1; /*la porta é quella di default*/ por=portad; /*confronto i parametri in ingresso*/ if(argc > 1){ /*se é l'help,visualizzo l'aiuto*/ if(strcmp(argv[1],"--help") == 0) { printf("server in uso n"); printf("server la porta del socket diviene quella di default (%i)n",portad); printf("server[sys] la porta del socket è distribuita dal sistema operativon"); printf("server --help aiutonn"); ext=1; } /*se la stringa é sys,il numero di porta é assegnato dal sistema operativo*/ else if(strcmp(argv[1],"sys") == 0) por=0; else { printf("visualizzare l'aiuton"); 2agina p
  • 3. Reti di calcolatori - Fabiano Dalla Piazza ext=1; } } /*se parametri ok allora*/ if(!ext) { /*inizializzazione per WIN32*/ #ifdef WIN32 WSADATA wsaData; WSAStartup(0x0101,&wsaData); #endif /*creazione del socket di famiglia PF_INET,con servizio SOCK_STREAM,tipo TCP(0)*/ /*si crea un protocollo per ciascuna connessione*/ /*se riesco a creare il socket,configuro il suo indirizzo*/ if((skt=socket(PF_INET,SOCK_STREAM,0)) >= 0 && (!ext)){ /*la famiglia dell'indirizzo é AF_INET*/ skaddr.sin_family=AF_INET; /*l'indirizzo IP locale é INADDR_ANY,uno qualsiasi degli indirizzi IP*/ /*con cui la macchina viene riconosciuta in rete*/ skaddr.sin_addr.s_addr=INADDR_ANY; /*viene assegnata la porta*/ skaddr.sin_port=htons(por); /*eseguo il binding(assegnazione nome) tra socket e indirizzo della macchina locale*/ if(bind(skt,(struct sockaddr *) &skaddr,sizeof(skaddr)) >= 0){ /*binding riuscito:allora trovo il numero di porta e lo visualizzo*/ lun=sizeof(skaddr); /*se ottengo il nome del socket*/ if(getsockname(skt,(struct sockaddr *) &skaddr,&lun) >= 0){ printf("server(locale):il numero della porta e' %dn",ntohs(skaddr.sin_port)); /*il server comunica che é disposto ad accettare connessioni accodate*/ /*fino a un massimo di 8 richieste(numero da me fissato)*/ if(listen(skt,8) >= 0){ /*se riesco a far lavorare il socket in modalità passiva*/ 3agina p
  • 4. Reti di calcolatori - Fabiano Dalla Piazza if((warn=fai(skt)) != 0) printf("server(locale):errore di elaborazionen"); /*chiusura della connessione TCP di client e server(direzione 2)*/ /*se la direzione é 0 chiude solo il server*/ /*se é 1 chiude solo il client*/ shutdown(skt,2); printf("server(locale):fine operazioni come richiesto dal clientn"); } else printf("server(locale):errore nel listenn"); } else printf("server(locale):errore nella ricerca nome socketn"); } else printf("server(locale):errore nel binding tra socket e macchinan"); } else printf("server(locale):errore nella creazione del socketn"); } return warn; } /*implementazione del sottoprogramma fai*/ /*il sottoprogramma esegue le direttive impartite dal client*/ int fai(int soce){ int sonum,abc,k,luind,numerop,erro,ext; struct sockaddr vie; char buffe[buffersiz],ord[buffersiz],prmt[3][buffersiz];/*matrice prmt*/ /*con massimo tre parametri*/ /*ciclo di processo delle richieste del client*/ abc=0; ext=0; 4agina p
  • 5. Reti di calcolatori - Fabiano Dalla Piazza erro=0; for(;!erro && !ext;){ /*fisso una lunghezza di indirizzo pari a 16*/ luind=16; /*la accept prende la prima richiesta in coda,crea un altro socket(sonum),se */ /*non ci sono richieste in sospeso,si blocca in attesa*/ if((sonum=accept(soce,&vie,&luind)) >= 0) { printf("server(locale):c' é una connessione (n.%u),elaboro n",abc); /*leggo quanti parametri invia il client*/ ricevi(sonum,ord,buffersiz); /*converto in intero e visualizzo numero parametri*/ numerop=atoi(ord); printf("numero parametri= %un",numerop); /*leggo il comando del client*/ ricevi(sonum,ord,buffersiz); /*controllo del comando del client*/ if(strcmp(ord,"ls") == 0 || strcmp(ord,"exit") == 0 || strcmp(ord,"test") == 0){ /*comando valido,allora considero il comando ricevuto*/ if(strcmp(ord,"exit") == 0){ /*richiesta di fine elaborazione*/ ext=1; /*invio il numero di righe che si trasmetteranno nel canale*/ invia(sonum,"2"); invia(sonum,"sono il server:fine elaborazioni "); } else{ /*se il comando non é exit,azzero i vecchi parametri*/ /*e leggo gli eventuali parametri rimanenti*/ /*ciclo fino a tre perché é l numero massimo di parametri che consento*/ for(k=0;k < 3;k++) prmt[k][0]='0'; for(k=0;k < numerop-1;k++){ 5agina p
  • 6. Reti di calcolatori - Fabiano Dalla Piazza ricevi(sonum,buffe,buffersiz); if(k < 3) /*salvo il comando,(3) é sempre il max numero parametri*/ strcpy(prmt[k],buffe); } if(strcmp(ord,"test") == 0){ /*se il comando é test*/ invia(sonum,"2"); invia(sonum,"sono il server:eseguo il test "); } else{ /*caso in cui il comando é ls:il client cercherà nella directory*/ /*se la stringa é zero,non viene specificata una directory*/ /*su cui eseguire il listing*/ if(strcmp(prmt[0],"") == 0) ls(sonum,""); else ls(sonum,"r"); } } } else{ /*comando non valido*/ /*invio il numero di righe che si trasmetteranno nel canale*/ invia(sonum,"2"); invia(sonum,"comando non valido "); /*tolgo eventuali parametri passati nel canale*/ for(k=0;k < numerop-1;k++) ricevi(sonum,buffe,buffersiz); } printf("server(locale):connessione elaborata (n.%u)n",abc); /*chiusura del socket di comunicazione*/ closesocket(sock); abc++; } else erro= 1; 6agina p
  • 7. Reti di calcolatori - Fabiano Dalla Piazza } return erro; } /*procedura ls*/ void ls(int scke,char *wher){ int errore; DIR *direc=NULL; struct dirent *afd=NULL; char nmfl[24];/*massimo numero caratteri del nome file fissato a 24*/ errore=1; /*se non viene specificata una directory*/ if(*wher == '0') /*allora apro la directory locale del server*/ direc=opendir("."); /*altrimenti apro quella specificata per il listing*/ else direc=opendir(wher); /*se la directory non é vuota*/ if(direc != NULL){ /*avviso il client dell'arrivo di un numero imprecisato di righe*/ invia(scke,"0"); /*ciclo di lettura dei files*/ while(!errore && (afd=readdir(direc))!=NULL){ /*terminatore di stringa*/ #ifndef _DIRENT_HAVE_D_NAMLEN strncpy(nmfl,afd->d_name,afd->d_namlen+1); #else strcpy(nmfl,afd->d_name); #endif /*invio stringa al client*/ invia(scke,nmfl); } /*chiudo la directory*/ closedir(direc); /*avverto il client del termine flusso*/ if(!errore) 7agina p
  • 8. Reti di calcolatori - Fabiano Dalla Piazza invia(scke,"FINEFLUSSO"); } else{ /*errore nel parametro,avvertimento al client*/ invia(sd,"2"); invia(sd,"errore nel parametro ls"); } } /*il sottoprogramma invia manda pezzi di stringa al socket*/ /*in base ai dati forniti,e aggiunge un terminatore di fine stringa newline*/ int invia(int sid,char *str){ int dim,scr,siz,a,wri,exi; char newl[2]; /*trovo la lunghezza stringa e azzero i parametri contatore e uscita*/ siz=dim=strlen(str); a=0; exi=0; /*finché c'è stringa e non esco,invio un suo pezzo,*/ /*ricordo dove sono arrivato e scalo dal contatore*/ while(siz > 0 && (!exi)){ /*invio vero e proprio*/ wri=send(sid,str+a,siz,0); if(wri > 0){ a+=wri; siz-=wri; } /*errore in trasmissione:esco*/ else exi=1; } /*lunghezza stringa rimanente*/ scr=(strlen(str)-siz); /*aggiungo il carattere newline come terminatore di fine stringa*/ strcpy(newl,"n"); if(dim > 0 && str[dim-1]!='n'){ siz=strlen(newl); a=0; 8agina p
  • 9. Reti di calcolatori - Fabiano Dalla Piazza exi=0; while(siz > 0 && (!exi)){ wri=send(sid,newl+a,siz,0); /*errore,esco*/ if(wri <= 0) exi=1; else{ a+=wri; siz-=wri; } } scr=(strlen(newl)-siz); } /*restiruisco la lunghezza stringa rimanente*/ return scr; } /*il sottoprogramma ricevi legge un byte alla volta la stringa del socket sid,*/ /*la inserisce nel buffer,terminandola con null(come negli esempi),infine*/ /*restituisce il numero di caratteri della stringa*/ int ricevi(int sid,char *str,int siz){ int a,rea,exi; char c; a=0; exi=0; /*finché non devo uscire,eseguo un ciclo di lettura dal socket*/ /*un carattere alla volta*/ for(;!exi;){ rea=recv(sid,&c,1,0); /*caso standard:c'é il carattere e non é newline*/ if(rea == 1 && a < siz && c!='n'){ *(str+a)=c; a++; } /*se non ho carattere o esso é newline,esco*/ else if((rea == 0)||(rea == 1 && c == 'n')){ *(str+a)='0'; rea=a+1; exi=1; } /*in caso di errore,esco*/ else{ *(str+a)='0'; rea=-1; 9agina p
  • 10. Reti di calcolatori - Fabiano Dalla Piazza exi=1; } } /*restituisco il numero di caratteri eccetto il terminatore*/ return rea; } =================================================================================== =============================================================== /*CLIENT*/ /*TESINA SCRITTA IN C PER RETI DI CALCOLATORI A CURA DI FABIANO DALLA PIAZZA*/ /*UNIVERSITA' DEGLI STUDI DI TRIESTE*/ /*IL FILE E' COMPOSTO DAL PROGRAMMA PRINCIPALE(main) E DUE SOTTOPROGRAMMI(invia e ricevi).*/ /*IL MAIN CREA UN SOCKET IP ORIENTATO ALLA CONNESSIONE TCP DI DOMINIO INTERNET,GUARDA NELLA DNS E*/ /*OTTIENE IL NOME DELL'HOST SERVER.EFFETTUA LA CONNESSIONE,USA IL SOTTOPROGRAMMA INVIA PER MANDARE*/ /*AL SOCKET I PARAMETRI E IL COMANDO DA ESEGUIRE.USA IL SOTTOPROGRAMMA RICEVI PER SAPERE*/ /*QUANTI PARAMETRI RICEVERA' DALL'UTENTE,E IN BASE A CIO' SA QUANTE RIGHE SUCCESSIVE ATTENDERSI,*/ /*LE LEGGE CON IL SOTTOPROGRAMMA RICEVI,EVENTUALMENTE RICEVENDO UNA STRINGA DI "FINEFLUSSO"*/ /*QUALORA IL NUMERO DI RIGHE NON SIA NOTO A PRIORI.INFINE CHIUDE IL SOCKET.*/ /*IL SOTTOPROGRAMMA INVIA FRAMMENTA LA STRINGA RICEVUTA IN FRAMES E LI INVIA AL SOCKET,MENTRE*/ /*IL SOTTOPROGRAMMA RICEVI LEGGE LA STRINGA RICEVUTA E LA IMMETTE NEL BUFFER.*/ /*direttive di definizione al preprocessore*/ /*portad è la porta per default,buffersiz è la capacità di memoria residente nel buffer*/ /*poi ci sono le varie librerie*/ #include <stdio.h> #include <string.h> #ifndef unix #define WIN32 #include <windows.h> #include <winsock.h> #else #define closesocket close #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> 10agina p
  • 11. Reti di calcolatori - Fabiano Dalla Piazza #include <netdb.h> #endif #define portad 5193 #define buffersiz 500 /*prototipi delle funzioni di lettura e spedizione dati*/ /*sid é l'astrazione per la comunicazione di rete*/ int invia(int sid,char *str); int ricevi(int sid,char *str,int siz); /*corpo del programma*/ int main(int argc,char *argv[]){ int j,sock,numerop,uscita; struct hostent *hpt; struct sockaddr_in skaddr; char buff[buffersiz]; /*inizializzazione per WIN32*/ #ifdef WIN32 WSADATA wsaData; WSAStartup(0x0101,&wsaData); #endif if(argc < 4){ /*se non ho parametri a sufficienza*/ printf("client n"); printf("client <host_server> <porta> <exit> termina la connessionen"); printf("client <host_server> <porta> <ls> [file [">" file2]] directory remotan"); printf("client <host_server> <porta> <test> test della connessionen"); printf("nse la <porta> == default (allora la porta diviene quella di default (%i)nn",portad); } else{ /*se ho parametri sufficienti*/ uscita=0; /*creo un socket IP orientato alla connessione TCP*/ /*di dominio Internet PF_INET e tipo,protocollo SOCK_STREAM,0*/ if((sock=socket(PF_INET,SOCK_STREAM,0)) >= 0 && (!uscita)){ /*se creo il socket e non devo uscire*/ if((hpt= gethostbyname(argv[1])) != 0){ 11agina p
  • 12. Reti di calcolatori - Fabiano Dalla Piazza /*con la funzione gethostbyname ottengo il nome dell'host:guarda*/ /*nella DNS e ritorna il puntatore *hpt alla struttura*/ /*configurazione della struttura con famiglia di indirizzi AF_INET*/ /*per indirizzi TCP/IP,e mappa il nome di protocollo*/ /*di trasporto al numero di protocollo*/ skaddr.sin_family= AF_INET; memcpy(&skaddr.sin_addr.s_addr,hpt->h_addr,hpt->h_length); if(strcmp(argv[2],"def") == 0) /*confronto le due stringhe:se sono uguali uso la porta di default*/ skaddr.sin_port=htons(portad); else /*altrimenti se le due stringhe non sono uguali non uso*/ /*la porta di default*/ skaddr.sin_port=htons(atoi(argv[2])); /*connetto il server con connect*/ if(connect(sock,(struct sockaddr *) &skaddr,sizeof(skaddr)) >= 0){ /*invio il numero dei parametri,poi primo parametro,secondo parametro,etc..*/ /*sprintf invia l'output nel buffer*/ sprintf(buff,"%i",argc - 3); /*vengono inviati i parametri forniti dall'utente*/ invia(sock,buff); /*viene inviato il comando*/ invia(sock,argv[3]); /*se esistono altri parametri,invio anche quelli*/ for(j=4;j < argc;j++) invia(sock,argv[j]); /*leggo un byte alla volta dalla prima stringa del socket sock*/ /*quanti parametri riceverò e la inserisco nel buffer*/ ricevi(sock,buff,buffersiz); /*converto in intero*/ numerop=atoi(buff); /*se il numero di parametri è nullo,allora il*/ /*numero righe é imprecisato*/ 12agina p
  • 13. Reti di calcolatori - Fabiano Dalla Piazza if(numerop == 0){ /*risposta del server*/ printf("client:la risposta dal server é:n"); uscita=0; /*se non esco*/ for(;!uscita;){ /*leggo un byte alla volta la stringa del socket sock*/ /*e la inserisco nel buffer*/ ricevi(sock,buff,buffersiz); /*se la stringa ricevuta è FINEFLUSSO esco*/ /*dal ciclo:non ci sono più stringhe da leggere*/ if(strcmp(buff,"FINEFLUSSO")==0) uscita= 1; else printf("%sn",buff); } } else{ /*se il numero di righe non è zero*/ /*ci saranno numero di parametri-1 riga*/ printf("client:la risposta dal server é:n",numerop-1); /*cicla numero righe-1 volte*/ for (j=0;j < numerop-1;j++){ /*leggo un byte alla volta la stringa del socket sock*/ /*e la inserisco nel buffer*/ ricevi(sock,buff,buffersiz); /*visualizzo*/ printf("%sn",buff); } } } 13agina p
  • 14. Reti di calcolatori - Fabiano Dalla Piazza else /*se la connessione non riesce*/ printf("client:connessione col server non riuscita!n"); } else /*host sconosciuto o quantomeno indeterminabile*/ printf("client:errore hostn"); /*chiusura del socket di comunicazione*/ closesocket(sock); } else printf("client:creazione socket non valida!n"); } return 0; } /*il sottoprogramma invia manda pezzi di stringa al socket*/ /*in base ai dati forniti,e aggiunge un terminatore di fine stringa newline*/ int invia(int sid,char *str){ int dim,scr,siz,a,wri,exi; char newl[2]; /*trovo la lunghezza stringa e azzero i parametri contatore e uscita*/ siz=dim=strlen(str); a=0; exi=0; /*finché c'è stringa e non esco,invio un suo pezzo,*/ /*ricordo dove sono arrivato e scalo dal contatore*/ while(siz > 0 && (!exi)){ /*invio vero e proprio*/ wri=send(sid,str+a,siz,0); if(wri > 0){ a+=wri; siz-=wri; } /*errore in trasmissione:esco*/ else exi=1; 14agina p
  • 15. Reti di calcolatori - Fabiano Dalla Piazza } /*lunghezza stringa rimanente*/ scr=(strlen(str)-siz); /*aggiungo il carattere newline come terminatore di fine stringa*/ strcpy(newl,"n"); if(dim > 0 && str[dim-1]!='n'){ siz=strlen(newl); a=0; exi=0; while(siz > 0 && (!exi)){ wri=send(sid,newl+a,siz,0); /*errore,esco*/ if(wri <= 0) exi=1; else{ a+=wri; siz-=wri; } } scr=(strlen(newl)-siz); } /*restiruisco la lunghezza stringa rimanente*/ return scr; } /*il sottoprogramma ricevi legge un byte alla volta la stringa del socket sid,*/ /*la inserisce nel buffer,terminandola con null(come negli esempi),infine*/ /*restituisce il numero di caratteri della stringa*/ int ricevi(int sid,char *str,int siz){ int a,rea,exi; char c; a=0; exi=0; /*finché non devo uscire,eseguo un ciclo di lettura dal socket*/ /*un carattere alla volta*/ for(;!exi;){ rea=recv(sid,&c,1,0); /*caso standard:c'é il carattere e non é newline*/ if(rea == 1 && a < siz && c!='n'){ *(str+a)=c; a++; } 15agina p
  • 16. Reti di calcolatori - Fabiano Dalla Piazza /*se non ho carattere o esso é newline,esco*/ else if((rea == 0)||(rea == 1 && c == 'n')){ *(str+a)='0'; rea=a+1; exi=1; } /*in caso di errore,esco*/ else{ *(str+a)='0'; rea=-1; exi=1; } } /*restituisco il numero di caratteri eccetto il terminatore*/ return rea; } =================================================================================== =============================================================== 16agina p