PDA

Visualizza la versione completa : [c] crezione socket (ubuntu)


Leonhearth
04-02-2012, 14:12
Ho un problema, in pratica quando vado ad avviare client e server sembra andare tutto bene quando digito per una scelta dal client me la fa vedere e dp se voglio fare altro si blocca e mi dice che c' un errore sulla bind ..mi sapete dire il perch? C' qualcosa di errato nella creazione del server? Ecco il codice relativo alla creazione della socket :




void crea_socket()
{
int listenfd, connfd,ls_result,prezzo_prodotto_scelto,scelta_eff ettuata, acquisto;
struct sockaddr_in servaddr;
socklen_t sin_size;
short port;


listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);


if (listenfd < 0)
printf("Server: errore nella creazione della socket.\n");
else
printf("La Listening Socket e' partita\n");


port=4000;


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);

if (bind(listenfd,(struct sockaddr *) &servaddr, sizeof(struct sockaddr_in)) < 0)
printf("Server: errore durante la bind.\n"); //Rilevamento dell'eventuale errore durante la bind

ls_result = listen(listenfd, SOMAXCONN);

if (ls_result < 0)
printf("Server: errore durante la listen.\n"); //La listen non riuscita
else
printf("La Socket e' in Ascolto\n");

sin_size = sizeof(struct sockaddr_in);

acquisto = 0;

connfd = accept(listenfd, (struct sockaddr*) &servaddr, &sin_size);

recv(connfd, (char *)&scelta_effettuata, sizeof(int), 0);

printf("Messaggio Arrivato: %d \n", scelta_effettuata);
prezzo_prodotto_scelto = 0;

if (scelta_effettuata == 1)
invia_prodotti (connfd, acquisto);

if (scelta_effettuata == 2)
invia_prod_da_prenotare (connfd, acquisto, prezzo_prodotto_scelto);

if (scelta_effettuata == 3)
{
acquisto = 1;
invia_prodotti (connfd, acquisto);
}

}

oregon
04-02-2012, 15:36
Originariamente inviato da Leonhearth
...mi dice che c' un errore sulla bind ..

Sicuramente il messaggio d'errore sar un po' pi preciso ... ci dici *esattamente* qual ?

Leonhearth
04-02-2012, 15:44
il progrmma si compila durante l'esecuzione che mi esce quel messaggio, il messaggio che ho inserito io nel programma come controllo, cio "Server: errore durante la bind"

if (bind(listenfd,(struct sockaddr *) &servaddr, sizeof(struct sockaddr_in)) < 0) printf("Server: errore durante la bind.\n"); //Rilevamento dell'eventuale errore durante la bind

linoma
04-02-2012, 16:25
Credo che il problema possa essere il fatto che manchi un memset della struttura

Leonhearth
04-02-2012, 16:34
ho anche provato ad inserire
memset((void *)&servadd, 0, sizeof(servadd));
dopo l'assegnazione della port, ma niente :/

linoma
04-02-2012, 16:36
Ma il tuo problema e' sul client?

Leonhearth
04-02-2012, 16:52
nn saprei a questo punto mmmm provo a postare client e server riscritti cosi magari li potete provare anche voi:
server:


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <string.h>



void crea_socket();

void invia_prodotti(int remoteSocket, int acquisto);

void invia_prod_da_prenotare(int remoteSocket, int acquisto, double prezzo_prodotto_scelto);





int main()

{

crea_socket();

return 0;

}


void crea_socket()

{

int listenSocket; //Creazione della socket di ascolto

int remoteSocket; //Creazione della socket di ricezione



struct sockaddr_in Server_addr, Client_addr;
int scelta_effettuata, acquisto;


short port;
int ls_result, prezzo_prodotto_scelto;

socklen_t len;

listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);


if (listenSocket < 0)

printf("Server: errore nella creazione della socket.\n");

else

printf("La Listening Socket e' partita\n");




port = 4000;



memset((void *)&Server_addr, 0, sizeof(Server_addr));


Server_addr.sin_family = AF_INET;

Server_addr.sin_addr.s_addr = htonl(INADDR_ANY);


Server_addr.sin_port = htons(port);



if (bind(listenSocket,(struct sockaddr*)&Server_addr,sizeof(Server_addr)) < 0)

printf("Server: errore durante la bind.\n");



ls_result = listen(listenSocket, SOMAXCONN);


if (ls_result < 0)

printf("Server: errore durante la listen.\n");
else

printf("La Socket e' in Ascolto\n");




len = sizeof(Client_addr);


acquisto = 0;



if((remoteSocket = accept(listenSocket,(struct sockaddr*)&Client_addr, &len))<0){

perror("accept");

exit(1);}





printf("Accettata Connessione con Client: %s\n",inet_ntoa(Client_addr.sin_addr));





recv(remoteSocket, (char *)&scelta_effettuata, sizeof(int), 0);


printf("Messaggio Arrivato: %d \n", scelta_effettuata);

prezzo_prodotto_scelto = 0;



if (scelta_effettuata == 1)
invia_prodotti (remoteSocket, acquisto);



if (scelta_effettuata == 2)

invia_prod_da_prenotare (remoteSocket, acquisto, prezzo_prodotto_scelto);



if (scelta_effettuata == 3)

{

acquisto = 1;

invia_prodotti (remoteSocket, acquisto);

}



}







void invia_prodotti (int remoteSocket, int acquisto)

{

int i, prodotto_scelto;

double prezzo_prodotto_scelto;

char prodotti [6][50] = {"01. Frigorifero \t\t\t100,00 Euro\n", "02. Lavatrice \t\t125,10 Euro\n", "03. Forno \t\t\t\t56,50 Euro\n",

"04. Frullatore \t\t\t\t19,90 Euro\n", "05. Asciugatrice \t\t150,00 Euro\n", "06. Lavastoviglie \t\t\t120,50 Euro\n"};

double prezzi_prodotti [] = {100.00, 125.10, 56.50, 19.90, 150.00, 120.50};



printf ("Sto inviando:\n");



for (i=0; i<6; i++)
{

send(remoteSocket, prodotti[i], strlen(prodotti[i]),0);



printf ("%s", prodotti[i]);
}



if (acquisto == 0)
{

printf("Chiudo il Server\n");

close(remoteSocket);


crea_socket ();
}



if (acquisto == 1) //In questo caso l'utente vuole effettuare l'acquisto

{

printf ("Aspetto il codice prodotto.\n");

recv (remoteSocket, (char *)&prodotto_scelto, sizeof(int), 0);



printf ("Ho ricevuto il codice prodotto %d\n", prodotto_scelto);

printf ("Sto inviando:\n");

send(remoteSocket,prodotti[prodotto_scelto-1], strlen(prodotti[prodotto_scelto-1]),0);




printf ("%s", prodotti[prodotto_scelto-1]);

prezzo_prodotto_scelto= prezzi_prodotti[prodotto_scelto-1];



invia_prod_da_prenotare (remoteSocket, acquisto, prezzo_prodotto_scelto);


}

}







void invia_prod_da_prenotare (int remoteSocket, int acquisto, double prezzo_prodotto_scelto)


{

int i, prod_da_prenotare_scelto;



char prod_da_prenotare [4][50] = {"01. Telefono wireless \t\t\t25,00 Euro\n", "02. Tv 32p HD \t\t\t200,00 Euro\n",

"03. Lettore Blu-ray \t\t\t99,90 Euro\n", "04. I-Phone 4S \t\t\t599,90 Euro\n"};

double prezzi_prod_da_prenotare [] = {25.00, 200.00, 99.90, 599.90};

double prezzo_prod_da_prenotare_scelto=0;



printf ("Sto inviando:\n");



for (i=0; i<4; i++)
{

send(remoteSocket, prod_da_prenotare[i], strlen(prod_da_prenotare[i]),0);



printf ("%s", prod_da_prenotare[i]);

}



if (acquisto == 0)
{

printf("Chiudo il Server\n");

close(remoteSocket);




crea_socket ();

}



if (acquisto == 1)
{

printf ("Aspetto il codice del prodotto da prenotare.\n");

recv (remoteSocket, (char *)&prod_da_prenotare_scelto, sizeof(int), 0);



printf ("Ho ricevuto il codice del prodotto da prenotare %d\n", prod_da_prenotare_scelto);

printf ("Sto inviando:\n");

send(remoteSocket, prod_da_prenotare[prod_da_prenotare_scelto-1], strlen(prod_da_prenotare[prod_da_prenotare_scelto-1]), 0);



printf ("%s", prod_da_prenotare[prod_da_prenotare_scelto-1]);



prezzo_prod_da_prenotare_scelto = prezzi_prod_da_prenotare[prod_da_prenotare_scelto-1] + prezzo_prodotto_scelto;


send(remoteSocket, (char *)&prezzo_prod_da_prenotare_scelto, sizeof(double),0);



printf ("Invio al client la somma di %.2f e %.2f che fa %.2f\n", prezzi_prod_da_prenotare[prod_da_prenotare_scelto-1], prezzo_prodotto_scelto, prezzo_prod_da_prenotare_scelto);





printf("Chiudo il Server\n");

close(remoteSocket);



crea_socket ();

}

}



CLIENT:



#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <string.h>

#define PAUSE (getchar())



void stampa_inizio ();

void scelta ();

void elenco_prodotti (int scelta, int acquisto);

void elenco_prod_da_prenotare (int scelta);

void acquisto_prodotti_e_prod_da_prenotare (int clientsocket);

void elenco_prodotti_da_prenotare_acquisto (int clientsocket);





int main()

{

stampa_inizio ();

return 0;

}







void stampa_inizio ()

//Void function che stampa a video il men principale

{

printf ("Gestione rapporto Rivenditore/Grossista \n\n");

printf ("\t\t\t SCELTE EFFETTUABILI:\n");

printf (" 1. Visualizza prodotti\n 2. Visualizza prodotti da prenotare\n 3. Acquista/Prenota prodotto\n 4. Esci\n\n");

printf ("Scegliere una fra le opzioni rese disponibili: ");

scelta ();
}







void scelta ()

{

int scelta, acquisto;

acquisto = 0;

scanf ("%d", &scelta);

while ((scelta <1) || (scelta>4))

{

scelta = 0;

printf ("Hai digitato un valore non valido. Riprova scegliendo fra i 4 volri disponibili.\n");

printf ("Scegliere una fra le opzioni rese disponibili: ");

scanf ("%d", &scelta);

}



if (scelta == 1)
elenco_prodotti (scelta, acquisto);

if (scelta == 2)
elenco_prod_da_prenotare (scelta);

if (scelta == 3)

{

acquisto = 1;

elenco_prodotti (scelta, acquisto);

}
}







void elenco_prodotti (int scelta, int acquisto)

{

int clientsocket;

struct sockaddr_in addr;


int i, p;

short port;
char prodotti [100];
port = 4000;

memset((void *)&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");

addr.sin_port = htons(port);

clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (connect(clientsocket, (struct sockaddr*)&addr, sizeof(addr)) < 0)

printf("Errore nella connessione con il Server");

send(clientsocket,(char *)&scelta, sizeof(int),0);

for (i=0; i<6; i++)
{

p = recv (clientsocket, prodotti, 100,0);

prodotti[p]='\0';
printf ("%s", prodotti);
}

if (acquisto == 0)
{

PAUSE;

system ("clear");

stampa_inizio();

}

else
acquisto_prodotti_e_prod_da_prenotare (clientsocket);

}







void elenco_prod_da_prenotare (int scelta)

{

int clientsocket;
struct sockaddr_in addr;
int i, p;
short port;
char prod_da_prenotare [100];
port = 4000;

memset((void *)&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr("127.0.0.1");

addr.sin_port = htons(port);

clientsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (connect(clientsocket, (struct sockaddr*)&addr, sizeof(addr)) < 0)

printf("Errore nella connessione con il Server");


send(clientsocket,(char *)&scelta, sizeof(int),0);

for (i=0; i<4; i++)

{

p = recv (clientsocket, prod_da_prenotare, 100,0);

prod_da_prenotare[p]='\0';

printf ("%s", prod_da_prenotare);
}

PAUSE;

system ("clear");
stampa_inizio();

}







void elenco_prodotti_da_prenotare_acquisto (int clientsocket)
{

int i, p;

char prod_da_prenotare [100];



for (i=0; i<4; i++)
{

p = recv (clientsocket, prod_da_prenotare, 100,0);

prod_da_prenotare[p]='\0';

printf ("%s", prod_da_prenotare);
}

}







void acquisto_prodotti_e_prod_da_prenotare (int clientsocket)

{

int cod_prodotto, cod_prod_da_prenotare, p;

double totale;
char prodotto_scelto [50];
char prod_da_prenotare_scelto [50];


totale = 0;



printf ("--> Inserire il codice del prodotto desiderato: ");

scanf ("%d", &cod_prodotto);



while ((cod_prodotto < 1) || (cod_prodotto> 6))

{

cod_prodotto = 0;

printf ("Codice errato. Riprova.\n");

printf ("--> Inserire il codice del prodotto desiderato: ");

scanf ("%d", &cod_prodotto);

}



send(clientsocket,(char *)&cod_prodotto, sizeof(int),0);

p = recv (clientsocket, prodotto_scelto, 50,0);

prodotto_scelto[p]='\0';

printf ("%s\n", prodotto_scelto); //Stampo a video la stringa

elenco_prodotti_da_prenotare_acquisto (clientsocket);


printf ("--> Inserire il codice del prodotto da prenotare desiderato: ");

scanf ("%d", &cod_prod_da_prenotare);



while ((cod_prod_da_prenotare < 1) || (cod_prod_da_prenotare> 4))

{

cod_prod_da_prenotare = 0;

printf ("Codice errato. Riprova.\n");

printf ("--> Inserire il codice del prodotto da prenotare desiderato: ");

scanf ("%d", &cod_prod_da_prenotare);

}



send(clientsocket,(char *)&cod_prod_da_prenotare, sizeof(int),0);


p = recv (clientsocket, prod_da_prenotare_scelto, 50,0);

prod_da_prenotare_scelto[p]='\0';

printf ("%s\n", prod_da_prenotare_scelto);


recv (clientsocket, (char *)&totale, sizeof(double), 0);


printf ("ACQUISTI:\nProdotto: %s\nProdotto prenotato: %s\nTotale: %.2f Euro\n", prodotto_scelto, prod_da_prenotare_scelto, totale);

PAUSE;

system ("clear");



stampa_inizio();

}


E' tanto lo so @_@ ma ho bisogno d'aiuto XD

linoma
04-02-2012, 19:00
Credo che il problema stia nel fatto che tu rifaccia il bind su connessioni ancora aperte. Anche xche dici che la prima volta funziona tutto mi pare. Anche se la documentazione per Windows, l'implementazione di windows segue gli standard, qui (http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550%28v=vs.85%29.aspx) puoi trovare qualcosa di aiuto in particolare SO_REUSEADDR.

Leonhearth
05-02-2012, 11:35
ho provato a passare alle void funzion anche listensocket e ogni volta che chiudevo la remotesocket con close(remoteSocket); chiudevo anche la listensocket con close(listenSocket)
ma niente :\

Loading