2009-06-10 2 views
3

Ich habe eine Client/Server-Stil-Anwendung, die mit WCF kommuniziert, die alle gut funktioniert. Eine Funktion der Anwendung besteht darin, Dateien von Client-Rechnern auf den Server zu holen (Central Control).Wie kann ich den TCPListener an eine externe IP-Adresse binden?

Die zentrale Steuerung fordert eine Liste der Dateien in einem angegebenen Ordner auf dem Client an und öffnet einen Port mit Sockets für die Clients, mit denen sie sich verbinden und jede Datei streamen können. Es verwendet für jede Datei eine andere Portnummer.

Dies funktionierte gut beim Testen vor Ort, aber bei der Bereitstellung in unserer Kundenumgebung bekam ich die folgende Ausnahme.

The requested address is not valid in its context 
    at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress) 
    at System.Net.Sockets.Socket.Bind(EndPoint localEP) 
    at System.Net.Sockets.TcpListener.Start(Int32 backlog) 
    at System.Net.Sockets.TcpListener.Start() 
    at AMIGA.Library.TransferFile.listenerThread() 

Die IP-Adresse im Endpunkt ist ein 10. .. * Adresse. Ich googelte nach einer Antwort und der allgemeine Konsens war, dass mit TCPListener nicht mit einer externen IP-Adresse binden kann. Ich dachte nicht ein 10. .. * Adresse war extern.

Der Code, der die Ausnahme wirft, ist wie folgt:

tcpListener = New TcpListener(IEndPoint) 
Dim handlerSocket As Socket 
Dim thdHandler As Thread 
tcpListener.Start() 
RequestFile() 

Gibt es keine Möglichkeit, kann ich einen TcpListener für diesen Job verwenden? Welche Alternativen gibt es, wenn nicht und wie einfach wäre es, die Alternativen umzusetzen.

Bedenken Sie, dass wir keinen direkten Zugriff auf die Firewall-Konfiguration haben und eine Änderung einige Wochen dauern kann.

+0

Die Definition von "external" variiert stark abhängig vom Kontext ... aber Sie haben Recht, 10.0.0.1/8 ist als privates Subnetz bezeichnet. –

Antwort

2

Ihre Anwendung sollte nur an die interne IP-Adresse des Geräts gebunden werden. Das Problem ist, dass die Firewall die externe IP-Adresse nicht automatisch über Port Forwarding an die interne IP-Adresse weiterleitet. Da Sie nicht einfach die Firewall-Konfiguration ändern können, gibt es drei Alternativen:

  1. Verwenden UPnP (Universal Plug & Play) Befehle aus Ihrer Anwendung an den Router den ausgewählten Port zu öffnen. UPnP wird nicht für sicherere Firewall-Konfigurationen aktiviert.
  2. (Komplizierter) Verwenden Sie TCP Hole punching, um eine Verbindung durch die Firewall herzustellen.
  3. Ändern Sie den Sinn, damit die Clients eine Verbindung zum Server herstellen. Der Server öffnet einen Port dynamisch über einen UPnP-Befehl oder hat nur einen Block von Ports in der Firewall geöffnet, der von dieser Anwendung verwendet werden kann.

    Vergewissern Sie sich in beiden Fällen, dass die WCF-Verbindung durch Sicherheit geschützt ist, so dass niemand über den Port-Scan mitkommen und unberechtigt auf die Dateien zugreifen kann.

+0

Danke Mike, du hast uns einen guten Ochsen gegeben. Wir haben die Bindung von Localhost an die spezifische Netzwerkadresse der zentralen Kontrolle geändert. Das hat den Trick gemacht. – Hooloovoo

0

Diese Ausnahme tritt normalerweise auf, wenn Sie versuchen, an eine Adresse zu binden, die auf dem Computer nicht gültig ist. Ist die IP, an die Sie zu binden versuchen, einer der Netzwerkschnittstellen auf dem Computer zugewiesen?

+0

Die Verbindung kann über WCF (Service Model) hergestellt werden, und es kann gepingt werden, aber das Problem tritt auf, wenn die TcpListener.start-Methode aufgerufen wird. – Hooloovoo

+0

Ja, ich wollte nur sicherstellen, dass der IPEndpoint, den Sie in den Konstruktor von TcpListener übergeben, ein IPEndpoint ist, der auf Ihrem Computer gültig ist.Es sollte die IP einer Ihrer Netzwerkschnittstellen oder IPAddress.Any sein. – heavyd