
I thought I'd make some socket server that could handle the packets without needing to split.
Source:
BasicClient.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
namespace NetworkSocket
{
public class BasicClient
{
/// <summary>
/// The base socket.
/// </summary>
private Socket baseSocket;
/// <summary>
/// A boolean indicating whether or not the connection was accepted.
/// </summary>
private bool wasAccepted;
/// <summary>
/// Gets a boolean indicating whether or not the connection was accepted.
/// </summary>
public bool Accepted
{
get
{
return wasAccepted;
}
}
/// <summary>
/// Creates a new instance of BasicClient.
/// </summary>
/// <param name="serverSocket">The server socket.</param>
/// <param name="asyncResult">The async result.</param>
internal BasicClient(Socket serverSocket, IAsyncResult asyncResult)
{
try
{
baseSocket = serverSocket.EndAccept(asyncResult);
wasAccepted = true;
}
catch
{
wasAccepted = false;
}
}
/// <summary>
/// An event raised when the client is disconnected.
/// </summary>
internal ConnectionEvent onDisconnection;
/// <summary>
/// An event raised a packet is received.
/// </summary>
internal BufferEvent onReceive;
/// <summary>
/// Creates a new instance of BasicClient.
/// </summary>
/// <param name="addressFamily">The address family.</param>
/// <param name="socketType">The socket type.</param>
/// <param name="protocolType">The protocol type.</param>
public BasicClient(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType,
ConnectionEvent onDisconnection = null,
BufferEvent onReceive = null)
{
baseSocket = new Socket(addressFamily, socketType, protocolType);
if (onDisconnection != null)
this.onDisconnection = onDisconnection;
if (onReceive != null)
this.onReceive = onReceive;
}
/// <summary>
/// Begins to receive the header.
/// </summary>
public void ReceiveHeader()
{
receiveBuffer = new byte[4];
baseSocket.BeginReceive(receiveBuffer, 0, 4, SocketFlags.None, new AsyncCallback(ReceiveHeader_Callback), null);
}
/// <summary>
/// Begins to receive the body.
/// </summary>
public void ReceiveBody()
{
receiveBuffer = new byte[size - 4];
baseSocket.BeginReceive(receiveBuffer, 0, (size - 4), SocketFlags.None, new AsyncCallback(ReceiveBody_Callback), null);
}
/// <summary>
/// The size of the received packet.
/// </summary>
private ushort size;
/// <summary>
/// The type of the received packet.
/// </summary>
private ushort type;
/// <summary>
/// The buffer holding all data received.
/// </summary>
private byte[] receiveBuffer;
/// <summary>
/// The callback from ReceiveHeader.
/// </summary>
/// <param name="asyncResult">The async result.</param>
private void ReceiveHeader_Callback(IAsyncResult asyncResult)
{
try
{
SocketError err;
int hSize = baseSocket.EndReceive(asyncResult, out err);
if (err == SocketError.Success)
{
if (hSize == 4)
{
byte[] rBuffer = new byte[4];
System.Buffer.BlockCopy(receiveBuffer, 0, rBuffer, 0, 4);
DataPacket header = new DataPacket(rBuffer);
size = header.Size;
type = header.Type;
ReceiveBody();
}
else
Disconnect();
}
else
Disconnect();
}
catch
{
Disconnect();
}
}
/// <summary>
/// The callback from ReceiveBody.
/// </summary>
/// <param name="asyncResult">The async result.</param>
private void ReceiveBody_Callback(IAsyncResult asyncResult)
{
try
{
SocketError err;
int bSize = baseSocket.EndReceive(asyncResult, out err);
if (err == SocketError.Success)
{
if (bSize == (size - 4))
{
if (onReceive != null)
{
byte[] rBuffer = new byte[size];
System.Buffer.BlockCopy(receiveBuffer, 0, rBuffer, 4, bSize);
DataPacket dPacket = new DataPacket(rBuffer);
dPacket.Size = size;
dPacket.Type = type;
onReceive.Invoke(this, dPacket);
}
ReceiveHeader();
}
else
Disconnect();
}
else
Disconnect();
}
catch
{
Disconnect();
}
}
/// <summary>
/// A boolean indicating whether or not the client is disconnected.
/// </summary>
private bool alreadyDisconnected = false;
/// <summary>
/// Disconnecting the client.
/// </summary>
public void Disconnect()
{
if (alreadyDisconnected)
return;
alreadyDisconnected = true;
try
{
if (baseSocket.Connected)
baseSocket.Disconnect(false);
}
catch
{
}
if (onDisconnection != null)
onDisconnection.Invoke(this);
}
/// <summary>
/// Sends a packet.
/// </summary>
/// <param name="buffer">The packet to send.</param>
public void Send(byte[] buffer)
{
bool PacketSend = false;
try
{
if (PacketSend = Monitor.TryEnter(this, 50))
{
if (baseSocket.Connected)
{
baseSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Send_Callback), null);
}
else
Disconnect();
}
}
finally
{
if (!PacketSend)
Disconnect(); // lag
else
Monitor.Exit(this);
}
}
/// <summary>
/// Sends a packet.
/// </summary>
/// <param name="packet">The packet to send.</param>
public void Send(DataPacket packet)
{
bool PacketSend = false;
try
{
byte[] buffer = packet;
if (PacketSend = Monitor.TryEnter(this, 50))
{
if (baseSocket.Connected)
{
baseSocket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Send_Callback), null);
}
else
Disconnect();
}
}
finally
{
if (!PacketSend)
Disconnect(); // lag
else
Monitor.Exit(this);
}
}
/// <summary>
/// The callback from Send.
/// </summary>
/// <param name="asyncResult">The async result.</param>
private void Send_Callback(IAsyncResult asyncResult)
{
try
{
int send = baseSocket.EndSend(asyncResult);
if (send < 4)
Disconnect();
}
catch
{
}
}
/// <summary>
/// Connects the client to an end point.
/// </summary>
/// <param name="endPoint">The end point to connect to.</param>
/// <returns>Returns true if the client was connected.</returns>
public bool Connect(EndPoint endPoint)
{
try
{
int tries = 0;
while (!baseSocket.Connected && tries < 3)
{
baseSocket.Connect(endPoint);
Thread.Sleep(3000);
}
}
catch
{
}
return baseSocket.Connected;
}
/// <summary>
/// Connects the client to an end point from a specific IP Address and port.
/// </summary>
/// <param name="ip">The IP Address.</param>
/// <param name="port">The port.</param>
/// <returns>Returns true if the client was connected.</returns>
public bool Connect(string ip, int port)
{
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
int tries = 0;
while (!baseSocket.Connected && tries < 3)
{
baseSocket.Connect(endPoint);
Thread.Sleep(3000);
}
}
catch
{
}
return baseSocket.Connected;
}
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
namespace NetworkSocket
{
public delegate void ConnectionEvent(BasicClient basicClient);
public delegate void BufferEvent(BasicClient basicClient, DataPacket buffer);
/// <summary>
/// A basic class for a server socket.
/// </summary>
public class BasicServerSocket
{
/// <summary>
/// The header socket.
/// </summary>
private Socket baseSocket;
/// <summary>
/// Creates a new instance of BasicServerSocket.
/// </summary>
/// <param name="addressFamily">The address family.</param>
/// <param name="socketType">The socket type.</param>
/// <param name="protocolType">The protocol type.</param>
/// <param name="onConnection">An event raised when a connection is accepted.</param>
/// <param name="onDisconnection">An event raised when a connection is dropped.</param>
/// <param name="onReceive">An event raised when a packet is received.</param>
/// <param name="onDeclined">An event raised when a connection was not accepted.</param>
public BasicServerSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType,
ConnectionEvent onConnection = null,
ConnectionEvent onDisconnection = null,
BufferEvent onReceive = null,
ConnectionEvent onDeclined = null)
{
baseSocket = new Socket(addressFamily, socketType, protocolType);
if (onConnection != null)
this.onConnection = onConnection;
if (onDisconnection != null)
this.onDisconnection = onDisconnection;
if (onReceive != null)
this.onReceive = onReceive;
if (onDeclined != null)
this.onDeclined = onDeclined;
}
/// <summary>
/// An event raised when a client is connected.
/// </summary>
private ConnectionEvent onConnection;
/// <summary>
/// An event raised when a client is disconnected.
/// </summary>
private ConnectionEvent onDisconnection;
/// <summary>
/// An event raised when a connection was not accepted.
/// </summary>
private ConnectionEvent onDeclined;
/// <summary>
/// An event raised when a packet is received.
/// </summary>
private BufferEvent onReceive;
/// <summary>
/// Tells the socket to be put in a listening state.
/// </summary>
/// <param name="backlog">The backlog queue.</param>
public void Listen(int backlog)
{
baseSocket.Listen(backlog);
}
/// <summary>
/// Binds the socket to an end point.
/// </summary>
/// <param name="endPoint">The end point the socket should be bound to.</param>
public void Bind(EndPoint endPoint)
{
baseSocket.Bind(endPoint);
}
/// <summary>
/// Binds the socket to an end point from a specific IP Address and port.
/// </summary>
/// <param name="ip">The IP Address.</param>
/// <param name="port">The port.</param>
public void Bind(string ip, int port)
{
baseSocket.Bind(new IPEndPoint(IPAddress.Parse(ip), port));
}
/// <summary>
/// Tells the socket to start accept connections.
/// </summary>
public void AcceptConnections()
{
baseSocket.BeginAccept(new AsyncCallback(Accept_CallbacK), null);
}
/// <summary>
/// The callback from AcceptConnections.
/// </summary>
/// <param name="asyncResult">The async result.</param>
private void Accept_CallbacK(IAsyncResult asyncResult)
{
BasicClient client = new BasicClient(baseSocket, asyncResult);
if (client.Accepted)
{
if (onConnection != null)
{
if (onReceive != null)
client.onReceive = onReceive;
if (onDisconnection != null)
client.onDisconnection = onDisconnection;
onConnection.Invoke(client);
}
client.ReceiveHeader();
}
else if (onDeclined != null)
onDeclined.Invoke(client);
AcceptConnections();
}
}
}
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NetworkSocket
{
public unsafe class DataPacket
{
public DataPacket(byte[] buffer)
{
this.buffer = new byte[buffer.Length];
System.Buffer.BlockCopy(buffer, 0, this.buffer, 0, buffer.Length);
}
public DataPacket(ushort size, ushort type)
{
buffer = new byte[size];
WriteUInt16(size, 0);
WriteUInt16(type, 2);
}
private byte[] buffer;
protected byte[] Buffer
{
get
{
return buffer;
}
}
public byte* Ptr
{
get
{
fixed (byte* ptr = Buffer)
return ptr;
}
}
public ushort Size
{
get
{
return ReadUInt16(0);
}
set
{
WriteUInt16(value, 0);
}
}
public ushort Type
{
get
{
return ReadUInt16(2);
}
set
{
WriteUInt16(value, 2);
}
}
public void WriteSByte(sbyte value, int offset)
{
(*(sbyte*)(Ptr + offset)) = value;
}
public void WriteInt16(short value, int offset)
{
(*(short*)(Ptr + offset)) = value;
}
public void WriteInt32(int value, int offset)
{
(*(int*)(Ptr + offset)) = value;
}
public void WriteInt64(long value, int offset)
{
(*(long*)(Ptr + offset)) = value;
}
public void WriteByte(byte value, int offset)
{
(*(byte*)(Ptr + offset)) = value;
}
public void WriteUInt16(ushort value, int offset)
{
(*(ushort*)(Ptr + offset)) = value;
}
public void WriteUInt32(uint value, int offset)
{
(*(uint*)(Ptr + offset)) = value;
}
public void WriteUInt64(ulong value, int offset)
{
(*(ulong*)(Ptr + offset)) = value;
}
public void WriteStringWithLength(string value, int offset, out int nextoffset)
{
WriteByte((byte)(value.Length > 255 ? 255 : value.Length), offset);
offset++;
foreach (char c in value)
{
WriteByte((byte)c, offset);
offset++;
}
nextoffset = offset;
}
public void WriteString(string value, int offset)
{
foreach (char c in value)
{
WriteByte((byte)c, offset);
offset++;
}
}
public sbyte ReadSByte(int offset)
{
return (*(sbyte*)(Ptr + offset));
}
public short ReadInt16(int offset)
{
return (*(short*)(Ptr + offset));
}
public int ReadInt32(int offset)
{
return (*(int*)(Ptr + offset));
}
public long ReadInt64(int offset)
{
return (*(long*)(Ptr + offset));
}
public byte ReadByte(int offset)
{
return (*(byte*)(Ptr + offset));
}
public byte[] ReadBytes(int offset, int length)
{
byte[] bytes = new byte[length];
for (int i = offset; i < length; i++)
bytes[i] = (*(byte*)(Ptr + i));
return bytes;
}
public ushort ReadUInt16(int offset)
{
return (*(ushort*)(Ptr + offset));
}
public uint ReadUInt32(int offset)
{
return (*(uint*)(Ptr + offset));
}
public ulong ReadUInt64(int offset)
{
return (*(ulong*)(Ptr + offset));
}
public string ReadString(int offset, int length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
sb.Append((char)ReadByte(offset + i));
return sb.ToString().Replace("\0", "").Replace("\r", "");
}
public string ReadString(int offset)
{
byte size = ReadByte(offset);
offset++;
return ReadString(offset, size);
}
public byte[] ToArray()
{
byte[] newbuffer = new byte[Buffer.Length];
System.Buffer.BlockCopy(Buffer, 0, newbuffer, 0, Buffer.Length);
return newbuffer;
}
public static implicit operator byte[](DataPacket dPacket)
{
return dPacket.ToArray();
}
public static implicit operator DataPacket(byte[] Packet)
{
return new DataPacket(Packet);
}
}
}
Example usage:
Server:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Server
{
class Program
{
static void Main(string[] args)
{
NetworkSocket.BasicServerSocket server = new NetworkSocket.BasicServerSocket(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp,
new NetworkSocket.ConnectionEvent(OnConnection),
new NetworkSocket.ConnectionEvent(OnDisconnection),
new NetworkSocket.BufferEvent(OnReceive),
new NetworkSocket.ConnectionEvent(OnDeclined));
server.Bind("127.0.0.1", 9999);
server.Listen(100);
server.AcceptConnections();
Console.WriteLine("The server has started.");
while (true)
Console.ReadLine();
}
static void OnConnection(NetworkSocket.BasicClient Client)
{
Console.WriteLine("Connection.");
}
static void OnDisconnection(NetworkSocket.BasicClient Client)
{
Console.WriteLine("Disconnection.");
}
static void OnDeclined(NetworkSocket.BasicClient Client)
{
Console.WriteLine("Declined.");
}
static void OnReceive(NetworkSocket.BasicClient Client, NetworkSocket.DataPacket Packet)
{
Console.WriteLine("Receved. Type: {0} Size: {1}", Packet.Type, Packet.Size);
byte[] buffer = Packet;
foreach (byte b in buffer)
Console.Write(b + " ");
Console.WriteLine();
Packet.WriteUInt32(400, 6);
Client.Send(Packet);
Console.WriteLine("Send.");
}
}
}
Client:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Client
{
class Program
{
static void Main(string[] args)
{
NetworkSocket.BasicClient client = new NetworkSocket.BasicClient(
System.Net.Sockets.AddressFamily.InterNetwork,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Tcp,
new NetworkSocket.ConnectionEvent(OnDisconnection),
new NetworkSocket.BufferEvent(OnReceive));
Console.WriteLine("Press any key to connect...");
Console.ReadLine();
if (!client.Connect("127.0.0.1", 9999))
{
Console.WriteLine("Could not connect.");
return;
}
client.ReceiveHeader();
while (true)
{
Console.ReadLine();
NetworkSocket.DataPacket packet = new NetworkSocket.DataPacket(10, 5000);
packet.WriteByte(64, 5);
client.Send(packet);
Console.WriteLine("Send.");
}
}
static void OnDisconnection(NetworkSocket.BasicClient Client)
{
Console.WriteLine("Disconnection.");
}
static void OnReceive(NetworkSocket.BasicClient Client, NetworkSocket.DataPacket Packet)
{
Console.WriteLine("Receved. Type: {0} Size: {1}", Packet.Type, Packet.Size);
byte[] buffer = Packet;
foreach (byte b in buffer)
Console.Write(b + " ");
Console.WriteLine();
}
}
}
I hope you'll find this useful
Enjoy!






