TCP如何将数据包从客户端中继到服务器

时间:2018-11-15 03:53:41

标签: c# .net sockets networking tcp

所以我正在为游戏服务器创建自己的代理服务器。 到目前为止,我尝试连接到Terraria服务器,它说 Connecting..  然后,我启动服务器应用程序,该应用程序接受该特定IP和端口上的传入请求,并提示消息框提示"Connected",然后游戏从“正在连接...”变为“正在连接到服务器...”,但是它卡在那里,这很可能是因为我没有将流量从代理服务器重定向到服务器。对吧?

我一直试图.Write()进入流,但是我想写的是错误的流,是写到接受连接的流还是为传出流量创建新的流?

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

1 个答案:

答案 0 :(得分:1)

简化的实现可能看起来像这样。

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...");
    }
}

尽管应该进行改进:

  • 使其异步
  • 使其同时与多个TcpClient一起使用