views:

979

answers:

2

I have a client/server style application which communicates using WCF which all works great. One function of the application is to get files from client machines onto the server (Central Control).

The Central Control requests a list of file in a specified folder on the client and opens up a port using sockets for the clients to connect to and stream each file. It uses a different port number for each file.

This worked fine when testing locally but when deployed to our customers environment I started getting the following exception.

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()

The IP address in the end point is a 10...* address. I googled about for an answer and the general consensus was that with tcpListener cannot bind with an external IP Address. I didn't think a 10...* address was external.

The code that throws the exception is as follows:

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

Is there no way I can use a TcpListener for this Job? What alternatives are there if not and how easy would it be to implement the alternatives.

Bear in mind that we do not have access to the firewall configuration directly, and a change could take a number of weeks to be implemented.

A: 

That exception typically occurs when you are trying to bind to an address that is not valid on the machine. Is the IP you are trying to bind to assigned to one of the network interfaces on the machine?

heavyd
The connection can be made through WCF (Service Model), and it can be Pinged, but the problem occurs when the TcpListener.start method is called.
Hooloovoo
Yes, I just wanted to make sure that the IPEndpoint that you are passing into the constructor of TcpListener is an IPEndpoint that is valid on your machine. It should be the IP of one of your network interfaces or IPAddress.Any.
heavyd
+2  A: 

Your application should bind only to the internal IP address on the machine. The problem is that the firewall does not automatically pass the external IP address through to the internal IP address via Port Forwarding. Since you cannot easily modify the firewall configuration, there are 3 alternatives:

  1. Use UPnP (Universal Plug N Play) commands from your application to the router to open the selected port. UPnP will not be enabled for more secure firewall configurations.
  2. (More complicated) Use TCP Hole punching to establish a connection through the firewall.
  3. Change the sense so that the clients connect to the server. The server dynamically opens a port via a UPnP command or just has a block of ports open in the firewall for use by this application.

    For either case, be sure that the WCF connection is protected by security so that anyone else cannot come along via port scanning and access the files without authorization.

Mike
Thanks Mike, you gave us a good steer. We changed the binding from Localhost to the specific network address of the central control. That did the trick.
Hooloovoo