TCP/UDP Socket server on WAN

我怕爱的太早我们不能终老 提交于 2020-01-11 06:55:10

问题


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

    }

回答1:


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



来源:https://stackoverflow.com/questions/7018796/tcp-udp-socket-server-on-wan

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!