简体   繁体   中英

TCP how do I relay the packets from my client to the server

So I am working on creating my own proxy server for my game server. Whats happening so far is that I try to connect to my Terraria server and it says Connecting.. Then I start my server application which accepts incoming requests on that specific IP & port and it prompts a MessageBox saying "Connected" and then the game goes from "Connecting..." to "Connecting to server..." but it gets stuck there, this is most likely because I am not redirecting the traffic from my proxy server to my server.. Right?

I've been trying to .Write() to the stream but I think I am writing to the wrong stream, do I write to the stream that accepts connections or do I create a new stream for outgoing traffic?

public partial class MainWindow : Window
    {
        public static IPAddress remoteAddress = IPAddress.Parse("127.0.0.1");
        public TcpListener remoteServer = new TcpListener(remoteAddress, 7777);
        public TcpClient client = default(TcpClient);

        public TcpClient RemoteClient = new TcpClient("terraria.novux.ru", 7777);

        public MainWindow()
        {
            InitializeComponent();
        }

        private void BtnListen_OnClick(object sender, RoutedEventArgs e)
        {
            if (StartServer())
            {
                client = remoteServer.AcceptTcpClient();
                MessageBox.Show("Connected");
                var receivedBuffer = new byte[1024];

                //Should I write to this one instead?
                var clientStream = client.GetStream();

                var stream = RemoteClient.GetStream();

                while (client.Connected)
                    if (client.Connected)
                        if (client.ReceiveBufferSize > 0)
                        {
                            receivedBuffer = new byte[1024];
                            stream.Write(receivedBuffer, 0, receivedBuffer.Length);
                        }
            }
        }

        private bool StartServer()
        {
            try
            {
                remoteServer.Start();
                MessageBox.Show("Server Started...");
                return true;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
                throw;
            }
        }
    }

A simplified implementation could look like this.

public class Program
{
    public static void Main(string[] args)
    {
        StartTcpListener("localhost", 9000);
    }

    private static byte[] SendReceiveRemoteServer(string host, int port, byte[] data)
    {
        try
        {
            // Create a TcpClient.
            // Note, for this client to work you need to have a TcpServer 
            // connected to the same address as specified by the server, port
            // combination.
            var client = new TcpClient(host, port);

            // Get a client stream for reading and writing.
            //  Stream stream = client.GetStream();

            var stream = client.GetStream();

            // Send the message to the connected TcpServer. 
            stream.Write(data, 0, data.Length);

            Console.WriteLine("Sent to server: {0}", Encoding.ASCII.GetString(data));

            // Receive the TcpServer.response.

            // Read the first batch of the TcpServer response bytes.
            var bytes = new byte[256];
            var allBytes = new List<byte>();
            var i = stream.Read(bytes, 0, bytes.Length);

            // Loop to receive all the data sent by the client.
            while (i != 0)
            {
                allBytes.AddRange(bytes);

                bytes = new Byte[256];
                i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
            }

            Console.WriteLine("Received from server: {0}", Encoding.ASCII.GetString(data));

            // Close everything.
            stream.Close();
            client.Close();

            return allBytes.ToArray();
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }

        Console.WriteLine("\n Press Enter to continue...");
        return new byte[0];
    }

    private static void StartTcpListener(string host, int port)
    {
        TcpListener server = null;
        try
        {
            var ipHostInfo = Dns.GetHostEntry(host);
            var ipAddress = ipHostInfo.AddressList[0];

            // TcpListener server = new TcpListener(port);
            server = new TcpListener(ipAddress, port);

            // Start listening for client requests.
            server.Start();

            // Enter the listening loop.
            while (true)
            {
                Console.WriteLine("Waiting for a connection... ");

                // Perform a blocking call to accept requests.
                // You could also user server.AcceptSocket() here.
                var client = server.AcceptTcpClient();
                Console.WriteLine("Connected!");

                // Get a stream object for reading and writing
                var stream = client.GetStream();

                // Buffer for reading data
                var bytes = new Byte[256];
                var allBytes = new List<byte>();
                var i = stream.Read(bytes, 0, bytes.Length);

                // Loop to receive all the data sent by the client.
                while (i != 0)
                {
                    allBytes.AddRange(bytes);

                    bytes = new Byte[256];
                    i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
                }

                if (allBytes.Count > 0)
                {
                    Console.WriteLine("Received from client: {0}", Encoding.ASCII.GetString(allBytes.ToArray()));

                    var received = SendReceiveRemoteServer("localhost", 11000, allBytes.ToArray());

                    // Send back a response.
                    stream.Write(received, 0, received.Length);
                    Console.WriteLine("Sent to client: {0}", Encoding.ASCII.GetString(received));
                }

                // Shutdown and end connection
                client.Close();
            }
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }
        finally
        {
            // Stop listening for new clients.
            server.Stop();
        }

        Console.WriteLine("\nHit enter to continue...");
    }
}

Although improvements should be made:

  • make it async
  • make it work with multiple TcpClients at the same time

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM