I'm attempting to make a simple multiplayer game to learn the concepts of network programming.
Here's what I have so far:
I've got C# server and client apps; both using .Net UDP sockets, working (at least behind my router).
The server binds specifically to port 54000, and the client binds to 55000. For my testing, I run both the server and client on the same machine.
I port-forwarded 54000 in my router, and the client can send an init and input msgs to the server using my router's external ip address. The server sends update messages to the clients' ip:port combo he saw from the init message (also my external IP in this case, but not LAN ip) on 55000 and everything works (client sends input, server moves a quad around, server sends updates, client receives new quad position msg ).
If 54000 is not forwarded, the server does not not receive any messages from the client (this is my sanity check that the messages are not just being looped back to localhost or something). However, 55000 is not forwarded in my router, and the client still receives update messages from the server (this seems strange to me).
I instructed a friend to port-forward 55000 of his router to his machine( so the client can recv messages from the server) and run the client. My server does not appear to receive messages from him.
I know if I wanted to avoid all the port-forwarding, I would have to use NAT traversal strategies, but I thought my current environment (including port forwarding) should work for users on a different LAN for now.
tl;dr - With 'proper' ( to my knowledge ) port-forwarding of client port, why wouldn't a user on another LAN be able to reach my server (behind a LAN, but properly port-forwarded again ) ?
Do I need NAT Traversal techniques for this scenario?
As far as I know you do need NAT traversal, since your router will most likely block any traffic not initiated inside your LAN. The port forwarding does not help since the router sees that the packets come from the web.
If you have port forwarding enabled on the server, and the client sends the first packet, then that should be sufficient to make it work.
Btw: You should *not* bind the client to a particular port. Instead, you should let the IP stack assign a port automatically when sending the first packet out.
Similarly, when you receive a packet from a client, you should remember the full address (including port) that you saw from that client, and use that address to return the response. If you assume that the port will be 55,000 (or some other number,) then responses are unlikely to work behind NAT firewalls (which is almost everybody these days.)