- Home /
NAT Traversal - Open.NAT
I am using Open.NAT to port forward this server. I cannot connect to the TcpServer from a browser (which is easier to test). I cannot connect using my external IP address but I can using my internal IP address).
void UPNP()
{
var discoverer = new NatDiscoverer();
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
var device = discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts).Result;
var ip = device.GetExternalIPAsync();
Debug.LogFormat("The external IP Address is: {0} ", ip.Result);
device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, 0, "Game Server"));
device.CreatePortMapAsync(new Mapping(Protocol.Udp, port, port, 0, "Game Server"));
}
void Server()
{
var discoverer = new NatDiscoverer();
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
var device = discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts).Result;
var mappings = device.GetAllMappingsAsync().Result;
foreach (var mapping in mappings)
{
Debug.Log(mapping);
}
/*NetworkServer.Listen(port);
NetworkServer.RegisterHandler(MsgType.Connect, OnConnect);*/
var tcp = new TcpListener(IPAddress.Parse(internalIP), port);
tcp.Start();
TcpClient client = tcp.AcceptTcpClient();
Debug.Log("Connected");
}
UPNP is enabled on the router and the UPNP windows service is running. The script correctly returns the port maps so I can only assume that maybe the server isn't binding to the correct IP address.
Edit: For anyone interested this is the code that I got to work using Open.NAT.
void UPNP()
{
var discoverer = new NatDiscoverer();
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
var device = discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts).Result;
var ip = device.GetExternalIPAsync();
Debug.LogFormat("The external IP Address is: {0} ", ip.Result);
device.CreatePortMapAsync(new Mapping(Protocol.Tcp, port, port, 0, "Game Server"));
device.CreatePortMapAsync(new Mapping(Protocol.Udp, port, port, 0, "Game Server"));
}
void Server()
{
NetworkServerSimple server = new NetworkServerSimple();
server.Listen(port);
}
void Client()
{
netClient = new NetworkClient();
netClient.RegisterHandler(MsgType.Connect, OnConnect);
netClient.Connect(client_ip, port);
}
void OnConnect(NetworkMessage msg)
{
Debug.Log(msg);
}
Before I was thought that the problem was with the ports not being open but it was the method I was attempting to connect to the server.
So, I'm making some weird mistake, and that NatDiscoverer() is not being found, can anyone help?
Answer by Bunny83 · Jul 26, 2018 at 11:26 PM
Uhm you create your TCP listener with your "internalIP" (whatever that contains). You may want to use
new TcpListener(IPAddress.Any, port);
instead. Otherwise you should use your external ip.
Thank you for the suggestion.
Using IPAddress.Any results in the same behaviour as using the internal IP.
Using my external IP results in the error "SocketException: The requested address is not valid in its context."
I might try using a different server to test.
Yes, you're right ^^. You actually setup a port forwarding rule in the router, so of course the server has to listen on the local address. Though it's common to bind IPAddress.Any ("0.0.0.0")
Answer by thejeffkerman · Jul 27, 2018 at 11:15 AM
After investigating further it appears that using the tool http://canyouseeme.org/. It can see the server running on the port. I will continue testing but I cannot understand why looking up the address in the web browser does not do the same.
What exactly do you mean by "looking up the address in the web browser"? A web browser expects HTTP communication. If your TCP server does not represent an HTTP server any request the browser sends to your server will never be properly answered and the browser might wait endless until it runs in a timeout. What exactly do you want to do with the server?
If the tiny snippet you posted is all your server does, that would mean it only allows a single connection. Even if this connection is dropped no new connection will be accepted by your "server". In your code you don't do anything with the accepted client. You don't receive any data the client might have send to you (like the web request a browser sends to you) nor do you send anything back. For a webbrowser a request is finished either when the specified content length of the response has been read in the case of a keep alive connection, ot otherwise when the client connection is closed. You don't do anything at the moment.
If you need more help with this you need to include more code.
I see what you mean but my intention was to remove everything apart from the code that I was testing. As you said when I tested it before I would start the server and unity would freeze and wait for the TCP connection. I would connect to an address like "localhost" in the web browser unity would unfreeze and debug log a connection. No data after this is sent but the connection is made. However when I repeated this with the external ip address it didn't behave the same. I assume it is because web browsers connect differently to external addresses. I have made progress on this issue but now it appears that NetworkServer uses UDP and is not visible from (canyouseeme.org)[http://canyouseeme.org]. So I wonder how this is different to the TCPServer.
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
Another NAT punchthrough attempt failed. 1 Answer
are client hosted servers limited by my 20 person ccu? 0 Answers