Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello

I'm working on creating a server for a game I'm going to begin development on using Unreal Engine, however I want the server to be a WinForms application. My approach was to create a C# WinForms application which is able to accept TCP connections and store them, receive packets from any and broadcast if necessary. An example would be PacketPlayerDisconnect, when a player disconnects from the server, this packet is sent to all of the other clients and contains the playerID, so that player model is removed on the clients.

First of all I'd like to know whether this is the best approach or not, and if you have any advice.

EDIT: The following is solved in my solution

The way my code implements a packet system is by sending a byte array in the following format:

0 | 1 | 2...
data length | packetID | packet contents...

Bytes 1 and 2 allow me to construct the correct packet and populate its contents when it's received.

I'm seeing a strange issue where the server sends a single packet to the client and it says it receives 7. Here's the code:

Server:
public class GameServer
    {
        private Main main;
        private List<GameClient> clients = new List<GameClient>();

        #region Config
        private int port = 1123;
        #endregion

        #region Connection
        private TcpListener listener;
        private bool listening = false;
        private Thread listenThread;
        #endregion

        public GameServer(Main main)
        {
            this.main = main;
        }

        public void start()
        {
            listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
            listener.Start();

            listenThread = new Thread(listen);
            listenThread.Start();
        }

        public void stop()
        {
            listening = false;
            listener.Server.Close();
            listener.Stop();

            clients.ForEach((client) => client.disconnect());
        }

        private void listen()
        {
            listening = true;

            while(listening)
            {
                TcpClient client = listener.AcceptTcpClient();
                GameClient game_client = new GameClient(main, client);
                clients.Add(game_client);
                game_client.sendPacket(new PacketRawData("Hello, Client"));
            }
        }

Client:
public class GameClient
    {
        private Main main;
        private TcpClient client;
        private NetworkStream client_stream;
        private Thread listenThread;
        private bool listening;

        public GameClient(Main main, String ipAddress, int portNum)
        {
            this.main = main;
            client = new TcpClient();
            
            listenThread = new Thread(receive);
            listenThread.Start();

            client.Connect(ipAddress, portNum);
            client_stream = client.GetStream();
        }

        public void send(string message)
        {
            byte[] message_data = Encoding.UTF8.GetBytes(message);
            byte[] data = new byte[1 + message_data.Length];

            int message_length = message_data.Length;
            data[0] = (byte)message_length;

            for(int i = 0; i < message_length; i++) // place message bytes after length byte
            {
                data[i + 1] = message_data[1];
            }

            NetworkStream client_stream = client.GetStream();
            client_stream.Write(data, 0, data.Length);
            client_stream.Flush();

            main.logPacket(PacketDirection.SEND, message);
        }

        private void receive()
        {
            listening = true;

            while(listening)
            {
                if(client_stream.DataAvailable)
                {
                    byte[] length_byte = new byte[1];
                    client_stream.Read(length_byte, 0, length_byte.Length); // read first byte (length)

                    int data_length = length_byte[0];
                    byte[] data_bytes = new byte[data_length]; // read rest of data
                    client_stream.Read(length_byte, 0, length_byte.Length);

                    String data = Encoding.UTF8.GetString(data_bytes);

                    main.logPacket(PacketDirection.RECEIVE, data);
                }
            }            
        }
    }


What I have tried:

Using Wireshark to monitor packets, but it don't detect my interfaces

Using several methods to send/receive.
Posted
Updated 3-Dec-17 13:28pm
v2
Comments
________________ 4-Dec-17 2:36am    
When you will be tired of low-level problems, have a look at WCF (https://www.codeproject.com/Articles/406096/A-beginners-tutorial-for-understanding-Windows)

technology...
If you develop both - client and server - i do not see any reason to use primitive sockets.

1 solution

Solution: This piece of code was the problem:

for(int i = 0; i < message_length; i++) // place message bytes after length byte
{
        data[i + 1] = message_data[1];
}
There was a typo;
message_data[1];
should be
message_data[i];

This caused lots of "a"s to be sent instead of the correct message.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900