====== Server e client ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//13/08/2008//** \\ \\
Si realizzerà ,in Posix C , un server concorrente (capace di accettare più connessioni) in grado di autenticare gli utenti, e di presentare un prompt con servizio di eco dei comandi e anche data/ora.\\ Si realizzerà anche un client capace di utilizzare il suddetto server.\\
Il codice è ben commentato, ma qualora si volessero avere più informazioni sull'argomento sarebbe consigliabile sfogliare i seguenti testi:
* [[http://gapil.truelite.it/|GaPiL Guida alla Programmazione in Linux]]
* [[http://edu.os3.it/html/manual/impararec/|Imparare il C una guida per Linux]]
===== Il client in azione =====
Avvio il client:
./client 192.168.1.11 utente password
output:
Indirizzo server---> 192.168.1.11
socket creato!
Risposta del server: USER-OK
Risposta dal server: PASS-OK
Ci siamo loggati con successo.
server-> time
Risposta del server: Wed Aug 13 16:23:35 2008
server-> ecoooooo!!!
Risposta del server: ecoooooo!!!
server-> exit
Risposta del server: exit
Risposta del server: Connessione terminata correttamente.
===== Il server =====
**server.c**
#include
#include
#include
#include
#include
#include
#define MAX 8000
char user[]="utente";
char pass[]="password";
int server(void) {
char buff[MAX];
char localbuff[MAX];
struct sockaddr_in server;
struct sockaddr_in client;
int sd, temp_sd, i;
//int address_size;
socklen_t address_size ;
unsigned short port = 9000;
pid_t pid;
/* Creiamo il socket e riempiamo i campi della struttura
* server
*/
if ( (sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Errore nella craazione del server!\n");
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
/* assegnamo al socket un processo tramite la funzione BIND */
if (bind(sd, (struct sockaddr *)&server, sizeof(server)) < 0)
printf("Errore nella chiamata di sistema BIND!\n");
/* Mettiamolo in ascolto */
listen (sd, 20);
address_size=sizeof(client);
while(1) {
if ((temp_sd= accept(sd, (struct sockaddr *)&client, &address_size)) < 0){
perror("Errore nella chiamata ACCEPT\n");
exit (-1);
}
if ((pid = fork()) < 0) {
perror(" fork error\n");
exit(-1);
}
if (pid == 0) { /* sono nel figlio */
close(sd);
/*Riceviaimo i dati dal client */
//Riceviamo il nome utente
recv(temp_sd, buff, sizeof(buff),MSG_WAITALL);
printf("Nome utente : %s\n", buff);
//controlliamo il nome utente
if (strcmp(buff,user)==0){
sprintf(buff,"%s","USER-OK");
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
recv(temp_sd, buff, sizeof(buff), MSG_WAITALL);
printf("Password -->%s\n",buff);
if (strcmp(buff,pass)==0){
sprintf(buff,"%s","PASS-OK");
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
printf("Autenticato.\n");
while (strcmp(buff, "exit")!=0){//qui siamo autenticati
recv(temp_sd, buff, sizeof(buff), MSG_WAITALL);
//se l'utente digita il comando "time" il server restituisce la data
if (strcmp(buff,"time")==0){
time_t timeval;
timeval = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&timeval));
}
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
/*inserire altro codice per le funzionalita'
* del server*/
}
sprintf(buff,"%s", "Connessione terminata correttamente.");
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
close(temp_sd);
}else{
sprintf(buff,"%s","PASS-BUD");
printf("Non autenticato.\n");
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
close(temp_sd);
}
}else{
sprintf(buff,"%s","USER-BUD");
printf("Non autenticato.\n");
send(temp_sd, buff, sizeof(buff), MSG_WAITALL);
close(temp_sd);
}
}else { /* sono nel padre */
close(temp_sd);
}
}//chiude while
close(temp_sd);
return 0;
}
int main(int argc, char* argv[]){
server();
return 0;
}
===== Il client =====
**client.c**
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX 8000
int client(char* indirizzo_server, char *user, char* pass){
int sd;
struct sockaddr_in client;
struct hostent *hp;
unsigned short port = 9000;
char buff[MAX];
char risp[MAX];
/* Dobbiamo riempire la struttura client ma prima
* ci occorrono alcune
* informazioni che ricaviamo appoggiandoci
* alla struttura hp
*/
//solo per il debug
printf("\n\n Indirizzo server---> %s\n", indirizzo_server);
//--
hp = gethostbyname(indirizzo_server);
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(port);
client.sin_addr.s_addr =((struct in_addr*)(hp->h_addr))->s_addr;
/* Creiamo il socket */
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Errore nella creazione del socket!\n");
else
printf("socket creato!\n");
/* connettiamoci all'host */
if (connect(sd, (struct sockaddr *)&client, sizeof(client)) < 0){
printf("Errore di connessione!\n");
return -1;
}
/* Inviamo lo user */
sprintf(buff,"%s", user);
send(sd, buff, sizeof(buff), MSG_WAITALL);
/*riceviamo la risposta per lo user, se esiste chiede la password
* con la stringa USER-OK*/
recv(sd, buff, sizeof(buff), MSG_WAITALL);
sprintf(risp, "%s",buff);
printf("Risposta del server: %s\n", risp);
if (strcmp(risp,"USER-OK")==0){
//se l'utente è stato accettato, invio la password
sprintf(buff,"%s",pass);
send(sd, buff, sizeof(buff), MSG_WAITALL);
//la risposta alla password
recv(sd, buff, sizeof(buff), MSG_WAITALL);
sprintf(risp,"%s",buff);
printf("Risposta dal server: %s\n\n",risp);
if (strcmp(risp,"PASS-OK")==0){
printf("Ci siamo loggati con successo.\n");
/*siamo autenticati, mettere qui sotto le altre
* istruzioni*/
char cmd[80];//per il prompt dei comandi
while (strcmp(risp,"exit")!=0){
printf("server-> ");scanf("%s",cmd);
sprintf(buff, "%s", cmd);
send(sd,buff,sizeof(buff),MSG_WAITALL);
recv(sd, buff, sizeof(buff), MSG_WAITALL);
sprintf(risp,"%s",buff);
printf("Risposta del server: %s\n",risp);
}
recv(sd, buff, sizeof(buff), MSG_WAITALL);
sprintf(risp,"%s",buff);
printf("Risposta del server: %s\n",risp);
}else{
printf("Password errata, il server ci ha sbattuti fuori.\n");
close(sd);
}
}else{
if (strcmp(buff, "USER-BUD")==0){
printf("Il server ci ha sbattuti fuori.\n");
close(sd);
}else{
printf("Altro errore inatteso.\n");
close(sd);
}
}
close(sd);
return EXIT_SUCCESS;
}
int
main (int argc, char *argv[])
{
client(argv[1],argv[2],argv[3]);
return 0;
}
===== Il makefile =====
CPP = gcc
all:
$(CPP) server.c -o server
$(CPP) client.c -o client
clean:
rm server
rm client