PDA

View Full Version : [C] Segmentation Fault!!! Socket in ambiente Unix


ginter87
14-01-2010, 19:16
Sto eseguendo un elaborato implementato con i socket e un altro popò di roba ma per adesso sto scrivendo la base per il collegamento. L'ho eseguito ma ... dal lato server è tutto ok! Si mette in attesa di connessioni ... mentre dal lato client .. dopo che inserisco l'indirizzo del server e della porta dove connettersi ... mi da "segmentation fault"

Perche mai?

Posto un pò il codice del client???

Ditemi voi e io lo faccio

grazie

||ElChE||88
14-01-2010, 19:39
Posto un pò il codice del client???
Direi... così è un po' vago. :fagiano:

ginter87
15-01-2010, 14:36
perciò ... è la prima volta che incollo codice, vediam come fare ...

questo è quello del CLIENT




#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>



#include "common.h"





int sd; //socket descriptor
int porta;
char indirizzo[20]; //indirizzo server

struct sockaddr_in server_addr;

struct hostent *hostinfo;

socklen_t len;



int main(int argc, char *argv[])

{
printf("inserisci l'indirizzo server\n");
scanf("%s",indirizzo);
printf("inserisci porta \n");
scanf("%d",&porta);


printf("Creo il socket\n");

sd = socket(AF_INET, SOCK_STREAM, 0);

if (sd < 0)

{

perror("Durante la creazione del socket\n");

exit(1);

}



// prepara i dati per la connessione con il server

server_addr.sin_family = AF_INET;

server_addr.sin_port = porta;

server_addr.sin_addr.s_addr = inet_addr(indirizzo);

hostinfo = gethostbyname(argv[1]);


if (hostinfo == NULL)

{

printf("Non è stato possibile risolvere il nome del server\n");

exit(1);

}

else

server_addr.sin_addr = *((struct in_addr *) hostinfo->h_addr);





printf("Apro la connessione\n");

if (connect(sd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)) < 0)

{

perror("Durante la connect");

exit(1);

}



// codice client di send e recv

printf("sono il client!!!!");

exit(0);

}







devo mettere anche quello del server???

ginter87
15-01-2010, 14:37
vabbè c'è un errore...avevo modificato il mio codice che inizialmente avevo scritto con inserimento dell'indirizoz del server su linea di comando ... ora invece glielo chiedo e metto l'indirizzo in una variabile ... c'è un argv[1] che devo modificare cmq il codice è questo :)

Teo@Unix
15-01-2010, 14:51
il codice d'errore che hai postato, specifica sui i sistemi unix, che si è tentato di scrivere in una zona di memoria in cui non era consentito farlo.
Probabilmente hai dimenticato di allocare memoria per una variabile o altro genere di cose...

non mi sono messo ad analizzare il codice ma se usi un debugger vai step per step fino a che non trovi l'istruzione che genera il problema di memoria.

ginter87
15-01-2010, 14:59
il codice d'errore che hai postato, specifica sui i sistemi unix, che si è tentato di scrivere in una zona di memoria in cui non era consentito farlo.
Probabilmente hai dimenticato di allocare memoria per una variabile o altro genere di cose...

non mi sono messo ad analizzare il codice ma se usi un debugger vai step per step fino a che non trovi l'istruzione che genera il problema di memoria.


d'accordo! Comunque non so cosa ho fatto di preciso a parte correggere quell'argv[1] ma non mi da piu quell'errore

me ne da un'altro -.-''

Il server va ok, specifica la porta da cui accettare le connessioni e si mette in attesa
quando eseguo il client invece



inserisci l'indirizzo server
127.0.0.1
inserisci porta
180
Creo il socket
Apro la connessione
Durante la connect: Connection refused

Teo@Unix
15-01-2010, 15:49
d'accordo! Comunque non so cosa ho fatto di preciso a parte correggere quell'argv[1] ma non mi da piu quell'errore

hai trovato il problema di memoria.


Durante la connect: Connection refused


il tuo client non si connette, potrebbero essere diversi i motivi... come funziona il server?

ginter87
15-01-2010, 16:07
ecco il codice



#include <stdio.h> // per I/O

#include <stdlib.h> // per exit, malloc, atoi...

#include <unistd.h> // per exec, getpid...

#include <pthread.h> // thread

#include <semaphore.h> //semafori posix

#include <sys/types.h> // standard posix
#include <netinet/in.h>

#include <sys/socket.h> // socket

#include <signal.h> // segnali

#include <string.h>
//manca libreria file





#include "common.h"

#define totpost 20

int sd;
int tab[totpost][2];


struct sockaddr_in server_addr; // struttura dati di configurazione

struct sockaddr_in client_addr;

socklen_t client_len;



int main(int argc, char *argv[])

{

printf("Server avviato con pid = %d\n", getpid());

int i;
int client_sd[totpost];
int port;


// preparazione dei dati relativi al bind

server_addr.sin_family = AF_INET;

server_addr.sin_port = port;

server_addr.sin_addr.s_addr = INADDR_ANY;

client_len = sizeof(struct sockaddr_in);



printf("inserisci la porta sulla quale accettare connesioni\n");
scanf("%d",&port);
int sd=socket(AF_INET, SOCK_STREAM, 0);
if(sd<0)
{
perror("creazione socket errata!!\n");
exit(-1);
}


printf("Effettuo il bind del socket con la porta \n", port);


if (bind(sd, (const struct sockaddr *) &server_addr, client_len) < 0)

{

perror("Durante il bind\n");

exit(1);

}



printf("Mi metto in attesa di connessioni sulla porta %d\n", port);

if (listen(sd, 20) < 0) //max 20 client

{

perror("Durante il listen");

exit(1);

}



printf("Entro nel ciclo infinito in cui accetto connessioni\n");



while (1)

{
// itero il tutto cn un ciclo for ke crea un sd dedicato per ogni client accettato
for(i=0;i<totpost;i++)
{


client_sd[i] = accept(sd, (struct sockaddr *) &client_addr, &client_len);
if (client_sd[i] < 0)
{
perror("Durante l'accept\n");
exit(1);
}
sleep(10);

pid_t pid = fork();
if (pid < 0)
{
perror("errore fork");
exit(1);
}
else if (pid > 0)
{
close(client_sd[i]);
}
else
{
printf("sono il servente: %d\n",getpid());
close(sd);

if (client_sd[i] < 0)

{

perror("Durante il close\n");

exit(1);

}



printf("Connessione con client accettata sul socket %d\n", client_sd[i]);



// manca una grossa parte di codice ke riguarda la gestione delle send e delle receive e del confronto



printf("Chiudo il socket %d dedicato con il client\n", client_sd[i]);

close(client_sd[i]);
exit(0);

}
}

}
}



:cry: :cry:

Teo@Unix
15-01-2010, 17:06
int sd=socket(AF_INET, SOCK_STREAM, 0);


stai inizializzando un socket basato su datagramma.:eek:

come ultimo parametro devi usare "IPPROTO_TCP", se vuoi usare TCP
la connect fallisce perchè non trova alcun socket TCP in ascolto...
mi sembra che l'errore sia anche nel client.... controlla, ho guardato velocemente.

||ElChE||88
15-01-2010, 17:38
stai inizializzando un socket basato su datagramma.:eek:

come ultimo parametro devi usare "IPPROTO_TCP", se vuoi usare TCP
la connect fallisce perchè non trova alcun socket TCP in ascolto...
mi sembra che l'errore sia anche nel client.... controlla, ho guardato velocemente.
Ma che stai dicendo?
Passando 0 decide da solo il protocollo appropriato basandosi sugli altri parametri. Se i parametri sono AF_INET e SOCK_STREAM indovina un po' che protocollo sceglierà? Eh già, TCP. ;)
Per il socket a datagrammi avrebbe dovuto specificare SOCK_DGRAM, non SOCK_STREAM.

Teo@Unix
15-01-2010, 18:22
Ma che stai dicendo?
Passando 0 decide da solo il protocollo appropriato basandosi sugli altri parametri. Se i parametri sono AF_INET e SOCK_STREAM indovina un po' che protocollo sceglierà? Eh già, TCP.
Per il socket a datagrammi avrebbe dovuto specificare SOCK_DGRAM, non SOCK_STREAM.


:fagiano: oh porca vacca, stavo guardando una cosa e ho risposto ad un'altra.... scusate .... hai ragione ||ElChE||88...
ero convinto di aver visto SOCK_DGRAM:D

ginter87
15-01-2010, 18:46
eh infatti!!!!!
Perciò .. definito che non ho sbagliato nella scelta del protocollo ... dei parametri vari ... secondo voi cosa ho sbagliato? :confused: :cry:

Teo@Unix
15-01-2010, 21:45
prova a debuggare anche il server, hai già verificato che il server sia ok? Prova anche ad eseguire tutto in macchina locale prima e su macchine separate poi...

clockover
15-01-2010, 22:52
Ti consiglio un paio di cose.
Quando associ una porta usa la funzione htons(porta), in questo modo ti converte il tuo intero nel valore riconosciuto dalla rete! E poi per la scelta della porta usa sempre un numero superiore a 5000, cioè da 5001 in poi!

Inoltre devi gestire i segnali! Specialmente nel server di sicuro lo ammazzi con CTRL-C! Gestendolo potrai chiudere il descrittore del socket ogni volta e poi uscire!

ti sparo un codice che ho usato un po di tempo fa per prova

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>

int sock_ds;

void sigint_handler(){
close(sock_ds);
exit(1);
}

int main(int argn, char ** argp){
sock_ds = socket(AF_INET, SOCK_STREAM, 0);
if(sock_ds == -1)exit(1);
signal(SIGINT, sigint_handler);
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(60000);
server.sin_addr.s_addr = INADDR_ANY;
if(bind(sock_ds, (struct sockaddr*)&server, sizeof(server)) == -1){
perror("Errore binding indirizzo");
close(sock_ds);
exit(1);
}
if(listen(sock_ds, 4) == -1){
perror("Errore listen");
close(sock_ds);
exit(1);
}
struct sockaddr_in client;
int client_ds;
int client_size = sizeof(client);
while(1){
client_ds = accept(sock_ds, (struct sockaddr*)&client, &client_size);
if(client_ds == -1)perror("Errore connessione client");
else{
//FAI QUELLO CHE TI PARE
}
}
}

ginter87
16-01-2010, 13:04
A che pro gestire i segnali?
Comunque ok, anche per il fatto della porta ... ho modificato quel lato ma il mio client continua ad essere rifiutato dal server :( :cry: :cry:

Ma se viene rifiutato ... il problema è nel client o nel server?
Ho provato a modificare il tuo codice per adattarlo al mio ... non ho commesso errori ma il mio client continua a non connettersi ... sigh!!!!!!!!!!

Perchè?

La porta è corretta per tutti e due, l'indirizzo, le istruzioni, dovrebbe essere tutto corretto =( :cry: :cry: :cry: mi viene da piangere perche se gia non va bene questo, quando dovrò implementare thread, semafori, file mi sparo come minimo :muro:

Teo@Unix
16-01-2010, 13:58
Hai provato su macchine separate?
Puoi usare una macchina virtuale.

magari è un qualche problema della tua macchina....

clockover
16-01-2010, 14:06
Anche eseguendo il mio codice ti da problemi?

Fai una prova... Esegui il mio server e connettiti con telnet

--> telnet localhost 60000

vedi un po se si connette!

ginter87
16-01-2010, 14:45
Hai provato su macchine separate?
Puoi usare una macchina virtuale.

magari è un qualche problema della tua macchina....


è strano però, ho altri codici solo sui socket che ci ha dato il prof ... e non ho mai avuto problemi ad eseguirli sia sulla stessa macchina che in macchine separate comunque ok proverò separatamente

ginter87
16-01-2010, 14:46
Anche eseguendo il mio codice ti da problemi?

Fai una prova... Esegui il mio server e connettiti con telnet

--> telnet localhost 60000

vedi un po se si connette!

cioè prendo il codice server tuo ... faccio ./server.c e poi? cioè aaaa scusami non so come connettermi col telnet :cry:


cioè so che vuol dire telnet.....

clockover
16-01-2010, 15:14
No aspe

gcc server.c -o server
./server


apri un altro terminale e dai
telnet localhost 60000

vedi se almeno si connette, non deve fare proprio nulla ma vedi se si connette!

ginter87
16-01-2010, 18:12
ecco cosa succede

ginter87@ginter-laptop:~$ telnet localhost 60000
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused


il terminale dove ho avviato il server è ancora fermo in attesa di connessioni
l'altro terminale invece..mi da quel messaggio

per adesso nn posso provare su macchine separate...

Teo@Unix
16-01-2010, 21:20
allega tutto il codice del server completo, così lo proviamo.

ginter87
01-03-2010, 18:28
allega tutto il codice del server completo, così lo proviamo.

Tutto fatto ... avrei altri problemi adesso ... ho messo un post apposito, sempre sullo stesso progetto
L'errore è Socket operation on non-socket ... se sai qualcosa al riguardo per favore cerca tra i miei post ... è l'ultimo!! Grazie di cuore a tutti quanti!

ginter87
01-03-2010, 18:54
scusami ma mi si è rotta la sfera di cristallo. :asd:

nuooooo :eek: vabbè dai grazie lo stesso :D

banryu79
02-03-2010, 00:28
... se sai qualcosa al riguardo per favore cerca tra i miei post ... è l'ultimo!! Grazie di cuore a tutti quanti!
:eek: Mecojoni, questa non l'avevo mai letta :asd: almeno il link all'altra discussione potevi metterlo...
Braccine corte? :rolleyes: I link non te li facciamo pagare, sono A gratisse ;)