[C, Reti di calcolatori] Socket Stream e Esercizio
Salve a tutti. Sto cercando di prendere dimestichezza con i socket in linguaggio c. Vorrei chiedervi un parere sullo sviluppo del seguente esercizio:
SocketStream: il cliente dovrà prendere due interi in standard input e inviarli al server. Il server dovrà ricevere i numeri e farne la somma andando a mandare il risultato al client.
CLIENT
SERVER
Pensate sia corretto ? Nel caso non lo fosse , quali sono gli errori?
SocketStream: il cliente dovrà prendere due interi in standard input e inviarli al server. Il server dovrà ricevere i numeri e farne la somma andando a mandare il risultato al client.
CLIENT
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define PROTOPORT 5193 //Porta Predefinita char localHost[] = "127.0.0.1"; //Host Predefinito char *host; int main(int argc, char *argv[]){ struct sockaddr_in socketAddress; //Struct per l'indirizzo di trasporto della socket server int sd; //Socket descriptor int port; //Numero di porta int n; //Byte letti int num1, num2, somma; //Per contenere i due interi e la somma inviata dal Server char buff[500]; //Buffer per i dati (letti/scritti) //Creazione di una Stream Socket sd = socket(PF_INET, SOCK_STREAM, 0); /* socket prende come argomenti la famiglia ( che specifica il formato degli indirizzi), il tipo di socket e un valore di protocollo (tipicamente impostato a zero ma in casi speciali esso è impostato diversamente). La funzione restituisce un piccolo valore intero --> descrittore di socket. */ //Se socket() restituisce un valore negativo --> ERRORE if(sd<0){ perror("Errore: creazione Socket fallita!"); exit(1); //Uscita dal programma } //Inizializzazione della memoria che dovrà contenere l'indirizzo della socket server memset((char *)&socketAddress,0,sizeof(socketAddress)); //Inizializzazione dell'indirizzo (socket server) socketAddress.sin_family = AF_INET; if(argc > 2) { }else{ port = PROTOPORT; } if(port>0){ socketAddress.sin_port = htons((u_short)port); /*L'ordine di byte usato in internet è diverso da quello tipicamente usato sul computer. Quindi attraverso la funzione htons bisogna convertire il numero della porta per poi assegnarlo al campo "sin_port" */ }else{ fprintf(stderr,"Numermo di porta %s non valido!",argv[2]); exit(1); } /*Verifica dell'immissione sulla linea di comando di Host alternativo. In tal caso il primo argomento su linea di comando sarà l'Host. Se niente è stato specificato --> HOST PREDEFINITO*/ if(argc>1){ host = argv[1]; }else{ host = localHost; } socketAddress.sin_addr.s_addr = inet_addr(host); //conversione Host //connect() tenta di effettuare una connessione con il server if((connect(sd, (struct sockaddr *)&socketAddress,sizeof(socketAddress)))<0){ perror("Connessione col Server Fallita!"); exit(1); } //Input dei due interi con conseguente invio al server dei dati printf("SOMMA DI DUE INTERI\n"); printf("Inserisci il primo numero da sommare: "); scanf("%d",(int*)buff); printf("Inserisci il secondo numero da sommare: "); scanf("%d",(int*)(buff+sizeof(int))); write(sd,buff,sizeof(buff)); //Lettura del risultato somma read(sd,buff,sizeof(buff)); printf("RISULTATO: %s",buff); close(sd); return 0; }
SERVER
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define PROTOPORT 5193 //Porta Predefinita #define QLEN 6 int main(int argc, char *argv[]){ struct sockaddr_in serverAddress; //Struct per l'indirizzo di trasporto della Socket server struct sockaddr_in clientAddress; //Struct per l'indirizzo di trasporto della Socket client int sd0,sd1; //Descrittori di Socket int port; //Numero di porta socklen_t alen; // "Address Length" char buff[500]; //Buffer per i dati(letti/scritti) int visite; //Tiene traccia delle visite al server da parte del client int num1, num2, somma; // Per due interi da sommare e l'intero risultato della somma //Creazione di una Stream Socket sd0 = socket(PF_INET, SOCK_STREAM, 0); /* socket prende come argomenti la famiglia ( che specifica il formato degli indirizzi), il tipo di socket e un valore di protocollo (tipicamente impostato a zero ma in casi speciali esso è impostato diversamente). La funzione restituisce un piccolo valore intero --> descrittore di socket. */ //Se socket() restituisce un valore negativo --> ERRORE if(sd0<0){ perror("Errore: creazione Socket fallita!"); exit(1); //Uscita dal programma } //Inizializzazione della memoria che dovrà contenere l'indirizzo della socket server memset((char *)&serverAddress,0,sizeof(serverAddress)); //Inizializzazione dell'indirizzo (socket server) serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY-->vengono accettati dati da qualunque parte vengano if(argc>1){ port = atoi(argv[1]); /* in port viene introdotto il numero di porta eventualmente introdotto come stringa sulla linea di comando convertito in intero dalla funzione atoi() */ }else{ port = PROTOPORT; //Altrimenti Porta predefinita } serverAddress.sin_port = htons((u_short)port); //conversione host //Bind assegna un indirizzo alla socket locale (server) . In caso di Errore viene restituito un valore negativo. if (bind(sd0,(struct sockaddr*)&serverAddress,sizeof(serverAddress))<0){ perror("Errore in fase di assegnamento indirizzo!"); exit(1); //Uscita dal programma } //Socket in ascolto e puà ricevere richieste di connessione. Se listen() restituisce -1 c'è stato un errore if(listen(sd0,QLEN)<0){ perror("Errore in fase di listen!"); exit(1); } alen = sizeof(clientAddress); while(1){ sd1 = accept(sd0, (struct sockaddr* )&clientAddress, &alen); //LEGGE VALORI DA SOMMARE read(sd1,buff,sizeof(buff)); num1 = *(int*)buff; num2 = *(int*)(buff + sizeof(int)); //EFFETTUA SOMMA somma = num1 + num2; sprintf(buff,"%d",somma); //MANDA IL RISULTATO AL CLIENT write(sd1,buff,sizeof(buff)); close(sd1); //chiusura della connessione col client } close(sd0); return 0; }
Pensate sia corretto ? Nel caso non lo fosse , quali sono gli errori?