You last visited: Today at 12:03
Advertisement
[Release] Socket Sample
Discussion on [Release] Socket Sample within the CO2 PServer Guides & Releases forum part of the CO2 Private Server category.
04/02/2012, 17:55
#1
elite*gold: 0
Join Date: Apr 2009
Posts: 782
Received Thanks: 458
[Release] Socket Sample
Yoo ^^
Found out in one of my studies an not so old socket system, and since i'm not using it anymore (got a new one ;P), its nearly copy+paste, but you can also check somethings if you want tho... It's not the best one, but it works without problems...
ServerSocket.cs:
Code:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using ConquerServer_v3_Msg.Common;
namespace ConquerServer_v3_Msg.Basecode
{
public delegate void Connection(ClientSocket pClient);
public delegate void Receive(ClientSocket pClient, Byte[] bufMsg);
public class ServerSocket// : GameThread
{
protected Socket m_sock;
protected int m_nPort;
protected Thread m_hThread;
protected ManualResetEvent m_asyncAcpt;
public Connection BeginAccept;
public Connection BeginClose;
public Receive BeginReceive;
public ServerSocket(int nPort)
{
m_nPort = nPort;
m_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
m_asyncAcpt = new ManualResetEvent(false);
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
}
public void Init(int nBacklog)
{
try
{
m_sock.Bind(new IPEndPoint(IPAddress.Any, m_nPort));
m_sock.Listen(nBacklog);
m_hThread = new Thread(new ThreadStart(OnTimer));
m_hThread.Priority = ThreadPriority.Normal;
m_hThread.Start();
}
catch (Exception ex)
{
Kernel.Print("ServerSocket.Init()", "Failure to accept a new connection.");
Kernel.LogPrint(ex.ToString());
}
}
protected void OnTimer()
{
try
{
while (true)
{
m_asyncAcpt.Reset();
m_sock.BeginAccept(new AsyncCallback(Accept), m_sock);
m_asyncAcpt.WaitOne();
}
}
catch (Exception ex)
{
Kernel.Print("ServerSocket.OnTimer()", "Failed to use ManualResetEvent.");
Kernel.LogPrint(ex.ToString());
}
}
protected void Accept(IAsyncResult pResult)
{
try
{
Socket newSock;
try { newSock = m_sock.EndAccept(pResult); }
catch (SocketException ex)
{
Kernel.Print("ServerSocket()", "Failure to accept a new connection.");
Kernel.LogPrint(ex.ToString());
newSock = null;
}
m_asyncAcpt.Set();
if (newSock != null)
{
ClientSocket pClient = new ClientSocket();
pClient.Open(newSock, this);
if (!pClient.IsOpen())
return;
if (BeginAccept != null)
BeginAccept.Invoke(pClient);
}
}
catch (SocketException ex)
{
Kernel.Print("ServerSocket.Accept()", "Logged error.");
Kernel.LogPrint(ex.ToString());
m_asyncAcpt.Set();
}
}
}
}
ClientSocket.cs:
Code:
using System;
using System.Net.Sockets;
using System.Text;
using ConquerServer_v3_Msg.NpcKernel;
using System.Threading;
using ConquerServer_v3_Msg.WorldKernel;
namespace ConquerServer_v3_Msg.Basecode
{
public class ClientSocket
{
protected string m_szIP;
protected User m_user;
protected EncryptServer m_encServer;
protected ServerSocket m_server;
protected Socket m_sock;
protected byte[] m_bufMsg;
protected int m_nLen;
protected byte[] m_bufSendMsg;
protected enum SKT_STATE { STATE_CLOSED = 0, STATE_OPEN };
protected SKT_STATE m_nState;
protected Thread m_hThread;
protected ManualResetEvent m_asyncRecv;
public User User { get { return m_user; } set { m_user = value; } }
public EncryptServer EncServer { get { return m_encServer; } set { m_encServer = value; } }
public bool IsOpen() { return m_nState == SKT_STATE.STATE_OPEN; }
public ClientSocket()
{
m_sock = null;
m_nLen = 0;
m_nState = SKT_STATE.STATE_CLOSED;
m_szIP = "";
}
public bool Open(Socket nSock, ServerSocket nServer)
{
m_sock = nSock;
m_server = nServer;
if (m_nState == SKT_STATE.STATE_OPEN)
return true;
if (m_nState == SKT_STATE.STATE_CLOSED)
{
m_nLen = 0;
m_bufMsg = new byte[1024];
m_nState = SKT_STATE.STATE_OPEN;
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
m_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
m_szIP = m_sock.RemoteEndPoint.AddressFamily.ToString();
m_asyncRecv = new ManualResetEvent(false);
m_hThread = new Thread(new ThreadStart(OnTimer));
m_hThread.Priority = ThreadPriority.Normal;
m_hThread.Start();
}
return true;
}
public void CreateCipher()
{
// if need an upate, there's no need to do a mess in the source code...
// so just create the encrypt server after the real login...
m_encServer = new EncryptServer();
}
public bool SendPacket(Byte[] bufMsg)
{
if (m_nState != SKT_STATE.STATE_OPEN)
{
Kernel.Print("ClientSocket.SendPacket()", "Client socket is closed.");
return false;
}
if (bufMsg == null)
{
Kernel.Print("ClientSocket.SendPacket()", "Nulled buffer detected.");
return false;
}
if (bufMsg.Length > 1024)
{
Kernel.Print("ClientSocket.SendPacket()", "Buffer length is higher than 1024.");
return false;
}
m_bufSendMsg = new Byte[bufMsg.Length];
Buffer.BlockCopy(bufMsg, 0, m_bufSendMsg, 0, m_bufSendMsg.Length);
m_encServer.Encrypt(ref m_bufSendMsg);
try { m_sock.BeginSend(m_bufSendMsg, 0, m_bufSendMsg.Length, SocketFlags.None, new AsyncCallback(EndSend), null); }
catch (SocketException ex)
{
Kernel.Print("ClientSocket.SendPacket()", "Logged error.");
Kernel.LogPrint(ex.ToString());
Disconnect(false);
return false;
}
return true;
}
public bool Disconnect(bool bNoLinger)
{
if (m_nState == SKT_STATE.STATE_CLOSED)
return false;
Abort();
if (m_sock != null)
{
try
{
m_nState = SKT_STATE.STATE_CLOSED;
m_sock.Shutdown(SocketShutdown.Both);
m_sock.Disconnect(bNoLinger);
m_sock.Close();
m_sock = null;
}
catch (SocketException ex)
{
Kernel.Print("ClientSocket.Disconnect()", "Logged error.");
Kernel.LogPrint(ex.ToString());
return false;
}
}
if (User != null)
{
Kernel.GetManager().Del(User.GetId());
MapGroup pMapGroup = MapGroupKernel.GetGroupById(User.GetMap());
pMapGroup.Del(User);
}
return true;
}
protected void OnTimer()
{
try
{
while (true)
{
m_asyncRecv.Reset();
if (m_sock != null)
m_sock.BeginReceive(m_bufMsg, 0, 1024, SocketFlags.None, new AsyncCallback(BeginReceive), null);
else
break;
m_asyncRecv.WaitOne();
}
}
catch (SocketException ex)
{
Kernel.Print("ClientSocket.OnTimer()", "Logged error.");
Kernel.LogPrint(ex.ToString());
Disconnect(false);
return;
}
}
public void Abort()
{
try
{
if (m_hThread != null)
{
m_hThread.Abort();
m_hThread = null;
}
if (m_asyncRecv != null)
{
m_asyncRecv.Close();
m_asyncRecv = null;
}
}
catch (Exception ex)
{
Kernel.Print("ClientSocket.Abort()", "Logged error.");
Kernel.LogPrint(ex.ToString());
m_hThread = null;
m_asyncRecv = null;
}
}
protected void BeginReceive(IAsyncResult pResult)
{
try
{
m_nLen = m_sock.EndReceive(pResult);
if (m_nLen > 0)
{ // proccess te received data if trully received it...
Byte[] bufMsg = new Byte[m_nLen];
Buffer.BlockCopy(m_bufMsg, 0, bufMsg, 0, m_nLen);
m_server.BeginReceive(this, bufMsg);
if (m_asyncRecv != null)
{
m_asyncRecv.Set();
return;
}
}
// Otherwise disconnect
Disconnect(false);
}
catch (SocketException ex)
{
Kernel.Print("ClientSocket.BeginReceive()", "Logged error.");
Kernel.LogPrint(ex.ToString());
Disconnect(false);
}
}
protected void EndSend(IAsyncResult pResult)
{
if (m_sock == null)
return;
try { m_sock.EndSend(pResult); }
catch (SocketException ex)
{
Kernel.Print("ClientSocket.EndSend()", "Logged error.");
Kernel.LogPrint(ex.ToString());
Disconnect(false);
}
}
}
}
Initialization method...
Code:
// Initialize the ServerSocket....
m_pSocket = new ServerSocket(5816);
m_pSocket.BeginAccept = new Connection(Connectors.BeginAccept);
m_pSocket.BeginReceive = new Receive(Connectors.BeginReceive);
m_pSocket.BeginClose = new Connection(Connectors.BeginClose);
m_pSocket.Init(10);
// -------------------------------
If you don't like it, just leave it... I'm not going to reply to stupid posts....
Cya ;P
04/02/2012, 23:41
#2
elite*gold: 21
Join Date: Jul 2005
Posts: 9,193
Received Thanks: 5,383
... why thread per client?
You're running mostly async and yet have a thread attached to each client object.
Non scalable <_<
04/03/2012, 01:06
#3
elite*gold: 12
Join Date: Jul 2011
Posts: 8,287
Received Thanks: 4,196
Quote:
Originally Posted by
pro4never
... why thread per client?
You're running mostly async and yet have a thread attached to each client object.
Non scalable <_<
You know... I typed up something similar to that... but he doesn't want feedback, so we should leave him alone and let his source go to pot (I guess).
04/03/2012, 05:04
#4
elite*gold: 0
Join Date: Apr 2009
Posts: 782
Received Thanks: 458
Quote:
Originally Posted by
Fаng
You know... I typed up something similar to that... but he doesn't want feedback, so we should leave him alone and let his source go to pot (I guess).
If you show me where i did say that, i give up coding....
@pro4ever
Yeah, that's why i changed the codes long time ago ;P like some 4 months i guess... there are like 100 ways of doing it....
04/03/2012, 05:42
#5
elite*gold: 0
Join Date: Apr 2008
Posts: 1,152
Received Thanks: 321
@Fang i know 12talis and hes not that type,
And he did say its old copy + paste, not like he went over it he most likely already fixed hes mistakes on he's newer one.
04/03/2012, 06:12
#6
elite*gold: 12
Join Date: Jul 2011
Posts: 8,287
Received Thanks: 4,196
Quote:
Originally Posted by
12tails
If you show me where i did say that, i give up coding....
@pro4ever
Yeah, that's why i changed the codes long time ago ;P like some 4 months i guess... there are like 100 ways of doing it....
I'm not gonna troll this thread and argue with you. "If you don't like it, just leave it"
does sound like you don't want people's feedback though. That's all I'm saying.
04/03/2012, 13:10
#7
elite*gold: 20
Join Date: Jun 2006
Posts: 3,296
Received Thanks: 925
Quote:
Originally Posted by
Fаng
I'm not gonna troll this thread and argue with you. "If you don't like it, just leave it" does sound like you don't want people's feedback though. That's all I'm saying.
And what exactly is wrong with that? He obviously doesn't want any feedback on something that he doesn't use nor care about as he already has a better and improved socket system.
04/03/2012, 13:16
#8
elite*gold: 20
Join Date: Mar 2006
Posts: 6,126
Received Thanks: 2,518
I would recommend that no one ever seriously consider using this for a production server, 1 thread per client as Pro stated doesnt scale well, you'll have all sorts of cross threading issues after a handful of clients, perhaps more if your very lucky.
04/05/2012, 02:32
#9
elite*gold: 0
Join Date: May 2008
Posts: 168
Received Thanks: 4
how ???
04/05/2012, 04:05
#10
elite*gold: 12
Join Date: Jul 2011
Posts: 8,287
Received Thanks: 4,196
Quote:
Originally Posted by
abdomiky7
how ???
Bend over
a book related to C# because nobody here can tell you how to implement it into your own source. If you don't know what it is, why are you even trying to implement it?
04/07/2012, 21:16
#11
elite*gold: 0
Join Date: Dec 2011
Posts: 1,537
Received Thanks: 785
One word. CPU-overload.
Async-handlers doesn't require another thread. That's why thei're async, unlike just synchronous.
04/08/2012, 00:13
#12
elite*gold: 0
Join Date: Apr 2009
Posts: 782
Received Thanks: 458
AsyncEventArgs work just wonderfully ^^
All times are GMT +2. The time now is 12:04 .