patterncsharpMinor
Asynchronous Server Sockets - Thread-Safety/Performance (MMO Gaming)
Viewed 0 times
gamingasynchronoussocketsthreadsafetyperformanceservermmo
Problem
I'm writing this game server for my small 2D MMO game.
So here are my questions:
```
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
public class Constanti
{
public const int CLASS_DARKELF_MAGICIAN = 1;
public const int CLASS_HUMAN_MAGICIAN = 2;
public const int CLASS_WARRIOR = 3;
public const int CLASS_MODERN_GUNMAN = 4;
public const int SUIT_1 = 1;
public const int SUIT_2 = 2;
public const int SUIT_3 = 3;
public const int SUIT_4 = 4;
public const int SUIT_Admin = 5;
//MAX/MIN
public const int MAX_LEVEL = 100;
public const int MAX_SKILL_LEVEL = 1000;
//SERVER MAX/MIN
public const int MAX_CONNECTIONS = 300;
public const int MAX_CONNECTIONS_IP = 54;
}
// State object for reading client data asynchronously
public class Player
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
//Player-Info
public int PlayerStats_Health = 0;
public int PlayerStats_Energy = 0;
public int PlayerInfo_Class = 0;
public int PlayerInfo_Suit = 0;
public int PlayerInfo_Level = 0;
public int PlayerInfo_SkillLevel = 0;
public void SetDefaults()
{
PlayerStats_Health = 100;
PlayerStats_Energy = 200;
PlayerInfo_Class = Constanti.CLASS_DARKELF_MAGICIAN;
PlayerInfo_Suit = Constanti.SUIT_1;
PlayerInfo_Level = 1;
PlayerInfo_SkillLevel = 1;
}
public Player()
{
}
p
So here are my questions:
- What do you think about the Thread-Safety of the code?
- Please explain how can it be made thread-safe / show example/ fix the thing if its not thread safe already.
```
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
public class Constanti
{
public const int CLASS_DARKELF_MAGICIAN = 1;
public const int CLASS_HUMAN_MAGICIAN = 2;
public const int CLASS_WARRIOR = 3;
public const int CLASS_MODERN_GUNMAN = 4;
public const int SUIT_1 = 1;
public const int SUIT_2 = 2;
public const int SUIT_3 = 3;
public const int SUIT_4 = 4;
public const int SUIT_Admin = 5;
//MAX/MIN
public const int MAX_LEVEL = 100;
public const int MAX_SKILL_LEVEL = 1000;
//SERVER MAX/MIN
public const int MAX_CONNECTIONS = 300;
public const int MAX_CONNECTIONS_IP = 54;
}
// State object for reading client data asynchronously
public class Player
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
//Player-Info
public int PlayerStats_Health = 0;
public int PlayerStats_Energy = 0;
public int PlayerInfo_Class = 0;
public int PlayerInfo_Suit = 0;
public int PlayerInfo_Level = 0;
public int PlayerInfo_SkillLevel = 0;
public void SetDefaults()
{
PlayerStats_Health = 100;
PlayerStats_Energy = 200;
PlayerInfo_Class = Constanti.CLASS_DARKELF_MAGICIAN;
PlayerInfo_Suit = Constanti.SUIT_1;
PlayerInfo_Level = 1;
PlayerInfo_SkillLevel = 1;
}
public Player()
{
}
p
Solution
Couple of things
-
Magic Number #1
This could be something like
You already have something like this set up in the Player Class
upon further inspection we see that this byte array isn't even used in the containing method, we should just get rid of it.
-
Magic Number #2
you should call this number something like
and call the listen method like this
-
In the
-
Naming for variables should be camelCase not PascalCase
You have some that are PascalCase
Some that are all lowercase
Be Consistent
-
Return something more meaningful in your exceptions, these probably shouldn't be shown to the user, you could also log these errors as well.
-
Magic Number #1
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];This could be something like
const int BUFFER_SIZE = 1024;
byte[] bytes = new byte[BUFFER_SIZE];You already have something like this set up in the Player Class
upon further inspection we see that this byte array isn't even used in the containing method, we should just get rid of it.
-
Magic Number #2
listener.Listen(50);you should call this number something like
const int LISTEN_TIME = 50;and call the listen method like this
listener.Listen(LISTEN_TIME);-
In the
StartListening method's catch statement you probably want to dispose the socket so that it isn't bound up the next time you call the method.-
Naming for variables should be camelCase not PascalCase
You have some that are PascalCase
Player ObjPlayerInfoSome that are all lowercase
Socket clientsocket = PlayerInfo.workSocket;Be Consistent
-
Return something more meaningful in your exceptions, these probably shouldn't be shown to the user, you could also log these errors as well.
Code Snippets
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];const int BUFFER_SIZE = 1024;
byte[] bytes = new byte[BUFFER_SIZE];listener.Listen(50);const int LISTEN_TIME = 50;listener.Listen(LISTEN_TIME);Context
StackExchange Code Review Q#27954, answer score: 5
Revisions (0)
No revisions yet.