|
|||||||
|
|
|
![]() |
|
|
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 18:40. |
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Quote:
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 |
|
|
|
|
|
|
#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 : 16-01-2010 alle 00: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 15: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: 22:00.




















