Pages: [1]   Go Down
Print
Author Topic: Bad address  (Read 3412 times)
0 Members e 1 Utente non registrato stanno visualizzando questa discussione.
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« on: 23-02-2010, 10:04:49 »

Vi è mai uscito questo errore da una read?

Non capisco a cosa si riferisca!

Faccio una read da client (per leggere un messaggio inviato dal server) e mi da come errore "Bad address"

Un aiutino?
« Last Edit: 23-02-2010, 13:01:02 by Nova » Logged

Ubuntu user:
#29872
n2o1988
Apprendista Forumista
**
Offline Offline

Gender: Male
Posts: 206



« Reply #1 on: 23-02-2010, 13:22:03 »

Vi è mai uscito questo errore da una read?

Non capisco a cosa si riferisca!

Faccio una read da client (per leggere un messaggio inviato dal server) e mi da come errore "Bad address"

Un aiutino?

A me non è mai capitato fin'ora. Posta il codice...
Logged
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #2 on: 26-02-2010, 16:09:23 »

La cosa è un po complessa:

Client:
Code:
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "incr.h"

int main (int argc, char * argv[])
{
CLIENT * cliente;
int s, snd, rcv;
struct sockaddr_in indirizzo;
int * risultato;

cliente = clnt_create("127.0.0.1",INCR_PROG,INCR_VERS,"tcp");
if(cliente == NULL)
{perror("assegnando client"); exit(-1);}

if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{perror("errore nella creazione della socket"); exit(1);}

indirizzo.sin_family = AF_INET;
indirizzo.sin_port = htons(6253);
char * ind = "127.0.0.1";
inet_aton(ind, &indirizzo.sin_addr);

if ((connect(s, (struct sockaddr *) &indirizzo, sizeof(indirizzo))) == -1)
{perror("errore nella connessione"); exit(2);}

printf("Client avviato...\n\n");

char * buffer = "Hi";
if ((snd = write(s, buffer, sizeof(buffer))) == -1)
{perror("Errore nella write"); exit(3);}

char * ricezione;
if ((rcv = read(s, &ricezione, 1024)) == -1)
{perror("Errore nella read"); exit(4);}

int i = atoi(ricezione);
risultato = incr_1(&i, cliente);

printf("Ecco fatto: %i", *risultato);

clnt_destroy (cliente);
close(s);
printf(">>> Termino <<<");
sleep(2);
exit(0);

}

Server:
Code:
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include "incr.h"

void killer();

int s, i, sock, addr_len, snd;
struct sockaddr_in indirizzo;
char * buffer;

int main (int argc, char ** argv)
{
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{perror("errore nella creazione della socket"); exit(1);}

indirizzo.sin_family = AF_INET;
indirizzo.sin_port =  htons(6253);
char * ip = "127.0.0.1";
inet_aton(ip, &indirizzo.sin_addr);

if ((bind(s, (struct sockaddr *) &indirizzo,  sizeof(indirizzo))) == -1)
{perror("errore nel binding"); exit(2);}

if ((listen(s, 1 )) == -1)
{perror("errore nel listen"); exit(3);}

signal(SIGINT, killer);

printf("server avviato... \t\t\t Premi CTRL+C per terminare\n");

while (1)
{
addr_len = sizeof(indirizzo);
sock = accept(s, (struct sockaddr *) &indirizzo, &addr_len );
if (sock == -1)
{perror("errore nell'accept"); close(sock); exit(4);}

int recv = read(sock, buffer, 1024);

if(recv == -1)
{perror("errore nel read"); close(sock); exit(5);}

if (sizeof(buffer) > 1)
{
printf("ricevuta comunicazione. Rispondo!\n");

char * buff ="33";

if((snd = write(sock, buff, recv)) == -1)
{perror("errore nel write"); close(sock); exit(6);}
}
}
}

void killer()
{
close(s);
close(sock);
printf(">>> Chiudo la connessione e termino <<<\n");
sleep(2);
exit(0);
}
Logged

Ubuntu user:
#29872
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #3 on: 26-02-2010, 17:33:56 »

Va beh, problema risolto:

La formattazione dei messaggi era del tutto errata, per questo dava quel messaggio.

Mi chiedo una cosa però:
Se faccio
Code:
while ((recv = read(s, buf, sizeof(buf)))>0)
{}

da un while del genere non esce mai. Se per esempio mando un messaggio ad un server con questa read, il server resterà bloccato sulla read. Come mai?

Il problema si risolve se levo il while...
Logged

Ubuntu user:
#29872
n2o1988
Apprendista Forumista
**
Offline Offline

Gender: Male
Posts: 206



« Reply #4 on: 27-02-2010, 01:53:24 »

Va beh, problema risolto:

La formattazione dei messaggi era del tutto errata, per questo dava quel messaggio.

Mi chiedo una cosa però:
Se faccio
Code:
while ((recv = read(s, buf, sizeof(buf)))>0)
{}

da un while del genere non esce mai. Se per esempio mando un messaggio ad un server con questa read, il server resterà bloccato sulla read. Come mai?

Il problema si risolve se levo il while...

Per caso il client che invia la richiesta, dopo la write rimane in attesa di una risposta del server (e quindi una read)? Perchè ho avuto anche io questo problema, ed in pratica la read restituisce 0 non appena il client chiude la connessione, ma se quest'ultimo non la chiude perchè a sua volta attende risposta dal server, il server non uscirà dal while.
Non ci ho studiato granchè (negli esempi del prof non ho trovato soluzioni), l'unica maniera che ho pensato sono messaggi di lunghezza prefissata (c'era un esempio nelle slide). In alternativa la read singola che come sappiamo non  è una buona soluzione...
Logged
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #5 on: 27-02-2010, 08:40:01 »

La situazione è esattamente quella che hai descritto e l'unico modo in cui, poco professionalmente ho risolto, è stata la singola read.

Purtroppo non riesco a venire a capo di questo problema...
Logged

Ubuntu user:
#29872
LtWorf
Forumista Esperto
****
Offline Offline

Posts: 1.079

Ogni cosa da me scritta è da intendersi come opinione personale e non come dato di fatto. Anche le eventuali dimostrazioni matematiche da me scritte saranno opinioni personali e quindi dovranno venire dimostrate da una terza parte di fiducia


WWW
« Reply #6 on: 27-02-2010, 10:44:17 »

La situazione è esattamente quella che hai descritto e l'unico modo in cui, poco professionalmente ho risolto, è stata la singola read.

Purtroppo non riesco a venire a capo di questo problema...

Non è un problema. Se programmate un server per leggere all'infinito lui legge all'infinito.

Intanto ricordo che se avete smesso di inviare dati ma volete ricevere un ultimo ack, potete utilizzare shutdown(2).

Faccio un esempio per HTTP. La connessione viene chiusa o quando il client chiude la connessione, oppure quando il client annuncia che dopo quella pagina, non richiederà altre pagine su quella connessione, quindi il server può chiudere la connessione. Naturalmente per fare questo è richiesta una elaborazione dei messaggi in arrivo, e non una semplice read che poi li butta via senza farsene nulla.
Il server può anche chiudere la connessione se è inattiva dopo un timeout, ma queste chiamate qui penso esulino dal programma.

Quindi per concludere: se scrivi un server che fa un while infinito con una read e che non ha logica interna è normale che non si comporti in modo logico!
Logged

There are some OO programming languages. I will create the first -_-' language.

LtWorf
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #7 on: 27-02-2010, 11:42:59 »

Quindi tu proponi di usare shutdown... uhm ma lo inserisco dove? Nel corpo del ciclo della read?
Logged

Ubuntu user:
#29872
LtWorf
Forumista Esperto
****
Offline Offline

Posts: 1.079

Ogni cosa da me scritta è da intendersi come opinione personale e non come dato di fatto. Anche le eventuali dimostrazioni matematiche da me scritte saranno opinioni personali e quindi dovranno venire dimostrate da una terza parte di fiducia


WWW
« Reply #8 on: 27-02-2010, 11:59:54 »

Quindi tu proponi di usare shutdown... uhm ma lo inserisco dove? Nel corpo del ciclo della read?

Ti ricordo che io non so cosa tu voglia fare. Prima chiarisci bene questo :-)
Logged

There are some OO programming languages. I will create the first -_-' language.

LtWorf
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #9 on: 01-03-2010, 08:30:27 »

Server:

Code:
while ((ret_socket = accept(s, (struct sockaddr *) &clnt_addr, &clnt_addr_len)) != -1)
{
while ((r = read(ret_socket, buffer, 1024)) >0) {}

printf("Ho letto il messaggio \n");
if (write(ret_socket, risp, sizeof(risp)) == -1)
{perror("errore nella risposta!"); exit(5);}
printf("Ho mandato %s\n", risp);
}

Client:

Code:
if ((write (s, buffer, sizeof(buffer))) == -1)
{perror("errore in scrittura"); exit(3);}
while ((r = read(s, risposta, 1024)) >0) {}
if (r == -1)
{perror("errore nella lettura della risposta"); exit(4);}
printf("Ricevuto %s\n" , risposta);

Questo codice: un semplice scambio di messaggi fra client e server da il problema della read che non ritorna mai. Lo shutdown in questo caso dove andrebbe?

Grazie ^^
Logged

Ubuntu user:
#29872
LtWorf
Forumista Esperto
****
Offline Offline

Posts: 1.079

Ogni cosa da me scritta è da intendersi come opinione personale e non come dato di fatto. Anche le eventuali dimostrazioni matematiche da me scritte saranno opinioni personali e quindi dovranno venire dimostrate da una terza parte di fiducia


WWW
« Reply #10 on: 01-03-2010, 09:14:22 »

Non ci siamo capiti.
Ti ho chiesto di dirmi (in italiano) che cosa vuoi che il tuo codice faccia. Se prima non stabiliamo questo, non ci sono risposte.
Logged

There are some OO programming languages. I will create the first -_-' language.

LtWorf
Nova
Forumista
***
Offline Offline

Gender: Male
Posts: 567


-.-"


WWW
« Reply #11 on: 01-03-2010, 10:14:16 »

Il client manda una stringa, il server la riceve e risponde. Quando il client riceve la risposta del server stampa un messaggio, tutto qua
Logged

Ubuntu user:
#29872
LtWorf
Forumista Esperto
****
Offline Offline

Posts: 1.079

Ogni cosa da me scritta è da intendersi come opinione personale e non come dato di fatto. Anche le eventuali dimostrazioni matematiche da me scritte saranno opinioni personali e quindi dovranno venire dimostrate da una terza parte di fiducia


WWW
« Reply #12 on: 01-03-2010, 13:50:05 »

E ci voleva tanto a dirlo? :-D

Dunque il server attualmente ha come condizione di uscita solamente la chiusura della connessione, il che ci va benissimo.
Però se il messaggio del client dovesse venire ricevuto con più di una read, esso verrebbe sovrascritto, il che ci va molto male.
La read dovrebbe leggere su buffer+qualcosa, dove qualcosa=0 inizialmente e poi è uguale al numero di byte già riempiti nel buffer. Inoltre nella condizione di uscita dovresti controllare anche che il buffer non vada in overflow.

Detto questo, dato che la stringa non è a lunghezza fissa e non sembra avere una sequenza di chiusura particolare (tipo bye di ftp), il client deve chiudere la connessione per fare uscire il server dalla read.
Solo che se chiudesse la connessione non potrebbe ricevere il messaggio dal server. Quindi usiamo shutdown nel client per comunicare che il client ha finito di inviare dati. A questo punto il server uscirà dal suo ciclo in cui legge e potrà inviare al client quello che vuole, e poi entrambi potranno chiudere completamente la connessione.
Logged

There are some OO programming languages. I will create the first -_-' language.

LtWorf
Pages: [1]   Go Up
Print
Jump to: