user470760
user470760

Reputation:

.NET TCP Server Dropping Connections

A while back I wrote a little application to implement a TCP Server, but as a newbie to C# .NET I just followed a tutorial. The authorization part of it works fine, but due to following the tutorial to closely, after the authorization is made, it drops the connection with tcpClient.Close();

How should I adjust this code to keep listening for more packets? I think most servers drop connections after X minutes, but I am still new to this type of thing.

// Starts the TCP RCON Server
public void StartServer()
{
    Console.WriteLine("RCON Server starting on Port: {0}", serverPort);

    this.tcpListener = new TcpListener(IPAddress.Any, serverPort);
    this.listenThread = new Thread(new ThreadStart(ListenForClients));
    this.listenThread.Start();

    Console.WriteLine("RCON Server has been Started.");
}

// Listen for Client Connections
private void ListenForClients()
{
    this.tcpListener.Start();

    while (true)
    {
        // blocks until a client has connected to the server
        TcpClient client = this.tcpListener.AcceptTcpClient();

        // Create a thread for client communication
        Thread clientThread = new Thread(new ParameterizedThreadStart(ReadClientPacket));
        clientThread.Start(client);
    }
}

private void ReadClientPacket(object client)
{
    TcpClient tcpClient = (TcpClient)client;
    NetworkStream clientStream = tcpClient.GetStream();

    bool terminate = false;

    while (!terminate)
    {
        try
        {
            int packetsize;

            // Create a new Packet Object and fill out the data from the incoming TCP Packets
            RCONPacket packet = new RCONPacket();

            using (BinaryReader reader = new BinaryReader(clientStream))
            {
                // First Int32 is Packet Size
                packetsize = reader.ReadInt32();

                packet.RequestId = reader.ReadInt32();
                packet.RconDataReceived = (RCONPacket.RCONDATA_rec)reader.ReadInt32();

                Console.WriteLine("Packet Size: {0} RequestID: {1} ServerData: {2}", packetsize, packet.RequestId, packet.RconDataReceived);

                // Read first and second String in the Packet (UTF8 Null Terminated)
                packet.String1 = ReadBytesString(reader);
                packet.String2 = ReadBytesString(reader);

                Console.WriteLine("String1: {0} String2: {1}", packet.String1, packet.String2);

                switch (packet.RconDataReceived)
                {
                    case RCONPacket.RCONDATA_rec.SERVERDATA_AUTH:
                    {
                        if (packet.String1 == "testpass")
                        {
                            Console.WriteLine("Password is Valid");
                            ReplyAuthRequest(packet.RequestId, tcpClient, packet.String1); // Junk Packet
                            ReplyAuthRequest(packet.RequestId, tcpClient, packet.String1);
                        }
                        else
                        {
                            Console.WriteLine("Password is Invalid");
                            ReplyAuthRequest(BAD_PASSWORD, tcpClient, packet.String1); // Junk Packet
                            ReplyAuthRequest(BAD_PASSWORD, tcpClient, packet.String1);

                            terminate = true;
                        }

                        break;
                    }
                    case RCONPacket.RCONDATA_rec.SERVERDATA_EXECCOMMAND:
                    {
                        Console.WriteLine("RCON Command Packet Received");
                        ReplyExecCommand(packet.RequestId, tcpClient);

                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            terminate = true;
        }
    }

    tcpClient.Close();
}

Upvotes: 2

Views: 1297

Answers (1)

user195488
user195488

Reputation:

If you notice, you have a lot of break statements. I am not clear on the entire design of your program, but if you remove those and then add a check for a boolean value in your while loop such aswhile(!terminated) { .. }, this would ensure that whenever your application tells the program to end or to stop listening, the loop will also be terminated because you would set terminated to true. What you are saying by while(true) is to continue forever until breakoccurs, which then subsequently breaks out of the while loop and calls .Close().

Upvotes: 4

Related Questions