|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
[C] Segmentation Fault!!! Socket in ambiente Unix
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 |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
|
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
perciò ... è la prima volta che incollo codice, vediam come fare ...
questo è quello del CLIENT Codice:
#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??? |
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
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
![]() |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
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. |
![]() |
![]() |
![]() |
#6 | |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
Quote:
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 Codice:
inserisci l'indirizzo server 127.0.0.1 inserisci porta 180 Creo il socket Apro la connessione Durante la connect: Connection refused |
|
![]() |
![]() |
![]() |
#7 | ||
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Quote:
Quote:
|
||
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
ecco il codice
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); } } } } ![]() ![]() |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
stai inizializzando un socket basato su datagramma.
![]() 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. |
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
Quote:
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. Ultima modifica di ||ElChE||88 : 15-01-2010 alle 17:40. |
|
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Quote:
![]() ero convinto di aver visto SOCK_DGRAM ![]() |
|
![]() |
![]() |
![]() |
#12 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
eh infatti!!!!!
Perciò .. definito che non ho sbagliato nella scelta del protocollo ... dei parametri vari ... secondo voi cosa ho sbagliato? ![]() ![]() |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
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...
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Oct 2004
Messaggi: 1945
|
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 Codice:
#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 } } } Ultima modifica di clockover : 15-01-2010 alle 23:15. |
![]() |
![]() |
![]() |
#15 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
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 ![]() ![]() ![]() 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 =( ![]() ![]() ![]() ![]() |
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Hai provato su macchine separate?
Puoi usare una macchina virtuale. magari è un qualche problema della tua macchina.... Ultima modifica di Teo@Unix : 16-01-2010 alle 14:05. |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Oct 2004
Messaggi: 1945
|
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! |
![]() |
![]() |
![]() |
#18 | |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
Quote:
è 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 |
|
![]() |
![]() |
![]() |
#19 | |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
Quote:
![]() cioè so che vuol dire telnet..... |
|
![]() |
![]() |
![]() |
#20 |
Senior Member
Iscritto dal: Oct 2004
Messaggi: 1945
|
No aspe
Codice:
gcc server.c -o server ./server Codice:
telnet localhost 60000 |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:20.