Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156

    [C++, linux] Socket, errore di binding 99

    sto iniziando ad entrare nel mondo dei socket linux, ma in questo codice:
    codice:
    #include <sys/types.h>        
    #include <sys/socket.h>
    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    using namespace std;
    
    int main()
    {
    //creazione socket
    int sockid;
    if ((sockid=socket(AF_INET,SOCK_STREAM,0))<0) cout<<"errore creazione\n"; else cout<<"socket: "<<sockid<<endl;
    
    
    //creazione struttura
    sockaddr indclient;
    indclient.sa_family=AF_INET;
    strncpy(indclient.sa_data,"QUALSIASI INDIRIZZO IP",sizeof(indclient.sa_data)-1); cout<<"address: "<<indclient.sa_data<<endl;
    
    //binding
     bind(sockid, (struct sockaddr *) &indclient, sizeof(struct sockaddr));
      cout<<"errore di bind() "<<errno;
    }
    il binding fallisce sempre, restituendo come errore "99" : EADDRNOTAVAIL: A nonexistent interface was requested or the requested address was not local.

    ho provato ad inserire diversi indirizzi ip, persino quello della macchina su cui è eseguito il programma, ma l'errore si presenta sempre.
    (l'indirizzo ip lo ottengo da qui: http://www.indirizzo-ip.com/ )

  2. #2
    sa_data non va usato, e in generale la struct sockaddr è "finta", nel senso che è un placeholder per la struttura contenente l'effettivo indirizzo (che varia a seconda del tipo di socket che stai collegando); nel caso specifico dei socket AF_INET, devi usare la struttura sockaddr_in (vedi ad esempio qui).

    Inoltre, non puoi fare un bind sull'IP fornito dal sito che dici, dato che con ogni probabilità quello è semplicemente l'indirizzo IP con cui il tuo router si presenta su internet.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    Interessante articolo, grazie, ho capito alcune cose di cui non ero sicuro, correggimi se sbaglio :

    client:
    con socket() creo il socket, fin qui ci siamo
    Con connect(), passando indirizzo del server e porta su cui è in ascolto, mi connetto al server
    Tutto il resto

    server:
    creo il socket
    E qui c'è la parte che non capisco :intendo dire
    ,nella struttura che passo a bind, oltre ad un numero di porta devo inserire anche un indirizzo, dove lo pesco? E sarà questo l'indirizzo che devo inserire nella struttura che passo a connect nel client?
    Tutto il resto

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    ho risolto diversi problemi completando il codice:

    server
    codice:
    #include <sys/types.h>   
    #include <sys/socket.h>
            #include <iostream>
            #include <string>
            #include <stdlib.h>
            #include <stdio.h>
            #include <string.h>
            #include <errno.h>
    #include <netinet/in.h>
    
    using namespace std;
    
    int main()
    {
    
    
    //creazione socket
    int sockid;
    if ((sockid=socket(AF_INET,SOCK_STREAM,0))<0) cout<<"errore creazione\n"; else cout<<"socket: "<<sockid<<endl;
    
    
    //creazione struttura
    sockaddr_in servaddr;
    bzero((char *) &servaddr, sizeof(servaddr)); //azzeramento
    servaddr.sin_family=AF_INET;
    servaddr.sin_port=htons(5001);
    servaddr.sin_addr.s_addr=INADDR_ANY;  //indirizzo qualsiasi
    
    //binding
    if (bind(sockid, (struct sockaddr *) &servaddr, sizeof(struct sockaddr))==-1) cout<<"errore di binding "<<(errno)<<endl; else cout<<"binding effettuato\n";
    
    //creo struttura del client
    sockaddr_in clientaddr;
    int clientid;  //nuovo id del client
    unsigned int dimensionid=sizeof(clientaddr); //dimensione della struttura
    
    //ascolto
    listen(sockid,1);
    cout<<"ascolto effettuato\n";
    
    //accetto
    clientid=accept(sockid,(sockaddr *) &clientaddr,&dimensionid); 
    if(clientid<0) cout<<"errore di accept\n";else cout<<clientid<<endl;
    
    sleep(5);
    
    }
    client:
    codice:
    #include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>
            #include <iostream>
            #include <string.h>
            #include <stdlib.h>
            #include <stdio.h>
            #include <strings.h>
            #include <errno.h>
    #include <netinet/in.h>
    #include <netdb.h>
    using namespace std;
    
    int main(){
    
    int sockid;
    if ((sockid=socket(AF_INET,SOCK_STREAM,0))<0) cout<<"errore creazione\n"; else cout<<"socket: "<<sockid<<endl;
    
    //ottengo l'indirizzo locale del server a partire dal "nome"
    hostent *hp;
    hp = gethostbyname("192.168.1.109");  //<--indirizzo locale
    
    //creo la struttura per il server
    sockaddr_in servaddr;
    bzero((char *) &servaddr, sizeof(servaddr)); //azzeramento
    servaddr.sin_family=AF_INET;
    servaddr.sin_port=htons(5001);
    bcopy( (char*)hp->h_addr,(char*)&servaddr.sin_addr.s_addr,hp->h_length );
    
    //connetto
    if (connect(sockid,(struct sockaddr *) &servaddr,sizeof(servaddr)) < 0) cout<<"errore di connessione\n"; else cout<<"connesso\n";
    
    sleep(5);
    
    }
    il fatto è che qui ho usato un indirizzo locale, se invece provo ad usare l'indirizzo ip (preso da quel sito di prima) e mettere i due programmi in macchine collegate a reti diverse la connessione non avviene. Sbaglio forse a scegliere l'indirizzo da passare a gethostbyname() ?

  5. #5
    Originariamente inviato da Rising1
    il fatto è che qui ho usato un indirizzo locale, se invece provo ad usare l'indirizzo ip (preso da quel sito di prima) e mettere i due programmi in macchine collegate a reti diverse la connessione non avviene. Sbaglio forse a scegliere l'indirizzo da passare a gethostbyname() ?
    L'indirizzo "esterno" non è il tuo indirizzo, è l'indirizzo del tuo router; devi fare la bind sul tuo indirizzo locale e fare un port forwarding sul tuo router. Leggiti la voce di Wikipedia sui NAT.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    Il port forwarding sul modem per aprire la porta che uso l'ho già fatto, mentre la bind sull'indirizzo locale non è quello che ho fatto sul server?

  7. #7
    Se hai fatto il port forwarding e stai facendo il bind sull'indirizzo locale la tua applicazione dovrebbe essere accessibile dall'esterno. Quello che non puoi fare è fare il binding direttamente sull'indirizzo esterno.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    156
    ok grazie, risolto, avevo sbagliato ad impostare un valore nel router (un technicolor che mi fa uscire pazzo...)

    sto aprendo un altro thread per un problema diverso ma sempre legato ai socket

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.