2

I have written a socket server in c# that will be used as the basic design for a small game project I am part of. The socket server works fine on lan. I able to communicate completely fine between the server and the client. However on the WAN the server receives all the correct messages from the client, but the client receives no messages from the server. Both the client and the server are behind a router but only the server's router has the ports forwarded. When the client connects to the server I get the IP address of the connection. Because the client is behind a NAT, is there more information from the sender that I need to collect? I assume the client could set up port forwarding but that would be VERY counter-productive to the game. Any help I can get is appreciated. If you need code let me know. Thanks in advance.

Used to make the TCP connection from the client

public string ConnectionAttempt(string ServeIP, string PlayUsername)
    {
        username = PlayUsername;

        try
        {

            connectionClient = new TcpClient(ServeIP,TCP_PORT_NUMBER);
            connectionClient.GetStream().BeginRead(readbuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);

            Login(username);
            ipAddress = IPAddress.Parse(((IPEndPoint)connectionClient.Client.RemoteEndPoint).Address.ToString());
            servIP = new IPEndPoint(ipAddress,65002);
            listenUDP = new IPEndPoint(ipAddress, 0);

            UDPListenerThread = new Thread(receiveUDP);
            UDPListenerThread.IsBackground = true;
            UDPListenerThread.Start();
            return "Connection Succeeded";
        }
        catch(Exception ex) {
            return (ex.Message.ToString() + "Connection Failed");
        }
    }

Listens for a UDP message on a thread.

private void receiveUDP()
    {
        System.Net.IPEndPoint test = new   System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
        System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
        server.Bind(serverIP);

        EndPoint RemoteServ = (EndPoint)servIP;
        while (true)
        {
            byte[] content = new byte[1024];
            int  data = server.ReceiveFrom(content, ref RemoteServ);

            string message = Encoding.ASCII.GetString(content);
            result = message;

            ProcessCommands(message);

        }
    }

Server TCP connection Listener:

private void ConnectionListen()
    {
        try
        {
            listener = new TcpListener(System.Net.IPAddress.Any, PORT_NUM);
            listener.Start();

            do
            {
                UserConnection client = new UserConnection(listener.AcceptTcpClient());
                client.LineRecieved += new LineRecieve(OnLineRecieved);
                UpdateStatus("Someone is attempting a login");

            } while (true);
        }
        catch
        {
        }
    }

Server UDP Listener:

private void receiveUDP()
    {
        System.Net.IPEndPoint test = new System.Net.IPEndPoint(System.Net.IPAddress.Any, UDP_PORT);
        System.Net.EndPoint serverIP = (System.Net.EndPoint)test;
        trans.Bind(serverIP);
        System.Net.IPEndPoint ipep = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 0);
        System.Net.EndPoint Remote = (System.Net.EndPoint)ipep;

        while (true)
        {

            byte[] content = new byte[1024];

            int recv = trans.ReceiveFrom(content,ref Remote);


            string message = Encoding.ASCII.GetString(content);
            string[] data = message.Split((char)124);
            //UpdateStatus(data[0] + data[1]);

            UserConnection sender = (UserConnection)clients[data[0]];
            sender.RemoteAdd = Remote;
            if (data.Length > 2)
            {
                OnLineRecieved(sender, data[1] + "|" + data[2]);
            }
            else
            {
                OnLineRecieved(sender, data[1]);
            }
        }
    }

Setup Information for a user connection Server-side:

Socket trans = new Socket(AddressFamily.InterNetwork,
                 SocketType.Dgram, ProtocolType.Udp); //UDP connection for data transmission in game.

    public PlayerLoc Location = new PlayerLoc();

    public UserConnection(TcpClient client)//TCP connection established first in the Constructor
    {
        this.client = client;
        ipAdd = IPAddress.Parse(((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
        ipep = new IPEndPoint(ipAdd, ((IPEndPoint)client.Client.RemoteEndPoint).Port);
        this.client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReciever), null);
    }

Method for sending data to individual users:

public void SendData(string data)//UDP only used during transmission
    {

        byte[] dataArr = Encoding.ASCII.GetBytes(data);
        trans.SendTo(dataArr, dataArr.Length,SocketFlags.None, RemoteAdd); 

    }
Stephen
  • 174
  • 4
  • 14
  • this may sound very silly (but we all sometimes make stupid mistakes) but you are not just sending UDP packets from the server to the client's IP address/port right? – Can Poyrazoğlu Aug 10 '11 at 22:48
  • I am getting the IP address from an initial login TCP connection first, then using UDP to send the messages back and forth. I will check but I believe they are being sent correctly. You are right double checking that sort of thing is definitely necessary – Stephen Aug 10 '11 at 22:52
  • Just check all of that out. I am getting the IP's and the Ports right because the server works inside the LAN – Stephen Aug 10 '11 at 22:56
  • ok, your client's UDP packets get to the server correctly, so server's inbound firewall/routing settings are set up correctly,no problem with that one. but you use the same ip/port to send back some UDP data, and it never reaches the client. so the client's router/nat simply doesn't forward the packets to the client or their firewall simply blocks that.. right? so the problem is at the client side – Can Poyrazoğlu Aug 10 '11 at 22:59
  • Yeah thats right. The server is all Port forwarded and working correctly, but I haven't set up any port forwarding on the client side because that would hurt the use-ability of the game latter on. – Stephen Aug 10 '11 at 23:01
  • so could you post the example code (both for client and the server). just the "connection" part (yes, you understand what I mean by "connection" for UDP), and have a look at those, see if it helps.. http://stackoverflow.com/questions/716620/udp-nat-and-setting-up-connections http://www.velocityreviews.com/forums/t370791-udp-packets-to-pc-behind-nat.html – Can Poyrazoğlu Aug 10 '11 at 23:12
  • Edited the original post with my code Sorry about the volume wanted to make sure it was all there. – Stephen Aug 10 '11 at 23:28
  • Doesn't warrant an answer, but also check your TTL on the packets. http://en.wikipedia.org/wiki/Time_to_live – Jonathan Dickinson Aug 11 '11 at 00:37
  • Checked that and I don't believe that is the problem. I think I have focused the problem down to the fact that the client is not receiving data over the WAN because the ports are not forwarded to the client and the ports are not staying open for the server to send the data through – Stephen Aug 11 '11 at 01:39

1 Answers1

2

The client must start the UDP communication so that it can get a "hole" in the router/firewall. And the UDP server must reply back using the end point referenced in ReceviedFrom

jgauffin
  • 99,844
  • 45
  • 235
  • 372