Domanda

Sto cercando di implementare il protocollo TCP perforazione con socket di Windows usando MinGW toolchain. Credo che il processo è giusto, ma il foro non sembra prendere. Ho usato questo come riferimento.

  1. A e B di connettersi al server S
  2. S invia a A , B 'il router IP + la porta è utilizzata per connettersi a S
  3. S fa la stessa cosa per il B
  4. A avviare discussioni 2:
    • si cerca filo conduttore a B 's router con le informazioni inviato da S
    • L'altro filo è in attesa di una connessione in ingresso sulla stessa porta utilizzata per connettersi al router quando collegato a S
  5. B fa la stessa

Non ho alcun problema nel codice credo che dal:

  • A e B fa arrivare l'altro IP e la porta per l'uso
  • Sono entrambi in ascolto sulla porta hanno usato per connettersi al router quando hanno contattato il server
  • Sono entrambi collegano al IP e la porta a destra, ma ottenere timeout (codice di errore 10060)

mi manca qualcosa?

Modifica Con l'aiuto di Process Explorer, vedo che uno dei client gestito per stabilire una connessione al peer. Ma il peer non sembra considerare il collegamento da effettuare.

Ecco quello che ho catturato con Wireshark. Per il bene di questo esempio, il server S e il client A sono sullo stesso PC. Il server S in ascolto su una porta specifica (8060) reindirizzato a quel PC. B cerca ancora di collegarsi al IP giusta perché vede che l'indirizzo pubblico di A inviato dal S è localhost e utilizza quindi l'IP pubblico di S , invece. (Ho sostituito gli IP pubblici da parte segnaposto)

Wireshark

EDIT 2 : Credo che la confusione è dovuta al fatto che entrambi i dati di richiesta di connessione ingresso e in uscita vengono trasferiti sulla stessa porta. Che sembra rovinare lo stato della connessione, perché non sappiamo quale presa otterrà i dati dalla porta. Se cito MSDN:

L'opzione presa SO_REUSEADDR permette una presa di forza associare a un porta in uso da un'altra presa. La seconda presa chiama setsockopt con il parametro optname insieme al SO_REUSEADDR e il set di parametri optval per un valore booleano di TRUE prima di chiamare bind sulla stessa porta come il presa originale. Una volta che la seconda presa ha legato con successo, la comportamento per tutte le prese legati a tale porta è indeterminato.

Ma parlando sulla stessa porta è richiesto dalla tecnica TCP Perforatura a aprire i fori

È stato utile?

Soluzione

A start 2 threads:
One thread tries connecting to B's router with the info sent by S
The other thread is waiting for an incoming connection on the same port used to connect to its router when it connected to S

You can't do this with two threads, since it's just one operation. Every TCP connection that is making an outbound connection is also waiting for an incoming connection. You simply call 'connect', and you are both sending outbound SYNs to make a connection and waiting for inbound SYNs to make a connection.

You may, however, need to close your connection to the server. Your platform likely doesn't permit you to make a TCP connection from a port when you already have an established connection from that same port. So just as you start TCP hole punching, close the connection to the server. Bind a new TCP socket to that same port, and call connect.

Altri suggerimenti

A simple solution to traverse into NAT routers is to make your traffic follow a protocol that your NAT already has an algorithm for forwarding, such as FTP.

  1. Use Wireshark to check tcp connection request(3-way Handhsake process) is going properly.

  2. Ensure your Listener thread is having select() to de-multiplex the descriptor.

  3. sockPeerConect(socket used to connect Other peer) is FD_SET() in Listener Thread.

  4. Ensure your are checking

     int Listener Thread()
     {
       while(true)
       {
           FD_SET(sockPeerConn);
           FD_SET(sockServerConn);
           FD_SET(nConnectedSock );
          if (FD_ISSET(sockPeerConect)
          {
            /// and calling accept() in side the
            nConnectedSock = accept( ....);
    
           }
           if (FD_ISSET(sockServerConn)
           {
            /// receive data from Server
            recv(sockServerConn );
    
           }
           if (FD_ISSET(nConnectedSock )
           {
            /// Receive data from Other Peer
             recv(nConnectedSock );
    
           }
    
       }
      }
    

5.Ensure you are simultaneously starting peer connection A to B and B to A.
6.Start your Listener Thread Prior to Connection to server and Peer and have Single Listener Thread for receiving Server and Client.

not every router supports tcp hole punching, please check out the following paper which explains in detail:

Peer-to-Peer Communication Across Network Address Translators

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top