Um den hochtechnischen Begriff zu verwenden, ist dies eigentlich ein ziemlich eklig Problem oder sogar ein paar eklige Probleme. Abhängig von der Konfiguration der Firewall werden normalerweise Antworten von einem anderen Endpunkt auf dem IP-Endpunkt zugelassen, wenn die Anforderung kam. Also ... wenn Ihr Freund das UDP-Datagramm unter Verwendung des Systemaufrufs recvfrom()
empfängt, empfängt der Adressparameter die IP-Endpunktinformationen, auf die er antworten soll. So sollte das andere Ende in der Lage sein, mit einem sendto()
unter Verwendung der gleichen Adressierungsinformationen zu antworten. Etwas wie:
/* initiator */
struct sockaddr_in hisaddr;
memset(&hisaddr, 0, sizeof(hisaddr));
hisaddr.sin_addr.s_addr = htonl(target_ip);
hisaddr.sin_port = htons(target_port);
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&hisaddr, sizeof(hisaddr));
/* receiver */
struct sockaddr_in peeraddr;
socklen_t peer_sz = sizeof(peeraddr);
recvfrom(sd, buf_ptr, buf_sz, 0, (struct sockaddr*)&peeraddr, &peer_sz);
/* build response */
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&peeraddr, peer_sz);
Die peeraddr
auf der anderen Seite wird Ihre externen Adresse oder, richtiger gesagt, die IP-Adresse Ihrer Firewall und die Port-Nummer sein, dass es zu benutzen gewählt haben. Die Portnummer, die Sie in Ihrem Code angeben, unterscheidet sich möglicherweise vollständig von dem Port, an den Ihr Freund Daten senden muss. Letztendlich ist es egal, welchen Port Sie verwenden möchten, da die Firewall möglicherweise an einem völlig anderen Port sendet und empfängt - darum geht es bei Network Address Translation. Ich würde empfehlen, RFC3235 für einige Tipps zu lesen, wie man diese Hürde überwinden kann.
Der beste Ansatz IMHO ist:
- Lassen Sie das Betriebssystem einen Port auswählen, indem entweder
bind()
mit einer Null-Port-Nummer anrufen oder den bind Überspringen insgesamt
- der Client die Adressinformationen aus der Steckdose erhalten zu haben Schicht (beispielsweise der fünfte und sechste Argumente
recvfrom()
)
- der Client sendet als Reaktion auf den abgerufenen Endpunkt in dem vorherigen Schritt
- die Firewall-Konfigurationen, bis die vorherigen Schritte Zwicken WO rk
Natürlich ist all die Magie im letzten Schritt. Wenn Sie NAT deaktivieren oder sicherstellen können, dass die Firewall niemals Ports umschaltet, funktioniert das auch, wenn Sie eine Port-Nummer und bind
-hingen. Je nachdem, wie Ihr Betriebssystem eingestellt ist, können Sie unter %WINDIR%\system32\drivers\etc\services
(oder /etc/services
) nachsehen, welche Portnummern reserviert oder allgemein verwendet werden.