diff --git a/.gitignore b/.gitignore index 6925e6f..2d908cd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ *.suo obj/ bin/ -*.bak \ No newline at end of file +*.bak +/EpServerEngine.cs/.vs/EpServerEngine.cs +/EpServerEngineSampleServer/.vs/EpServerEngineSampleServer/v15/Server/sqlite3 +/SL diff --git a/.gitmodules b/.gitmodules index 627e2a3..30d3398 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "EpLibrary.cs"] path = EpLibrary.cs - url = git@github.com:juhgiyo/EpLibrary.cs.git + url = https://github.com/limaolm/EpLibrary.cs.git diff --git a/EpServerEngine.cs/EpServerEngine.cs/ClientSide/IOCP/IocpTcpClient.cs b/EpServerEngine.cs/EpServerEngine.cs/ClientSide/IOCP/IocpTcpClient.cs index 86133ce..27c4ae9 100644 --- a/EpServerEngine.cs/EpServerEngine.cs/ClientSide/IOCP/IocpTcpClient.cs +++ b/EpServerEngine.cs/EpServerEngine.cs/ClientSide/IOCP/IocpTcpClient.cs @@ -1,128 +1,128 @@ -/*! -@file IocpTcpClient.cs -@author Woong Gyu La a.k.a Chris. - -@date April 01, 2014 -@brief IocpTcpClient Interface -@version 2.0 - -@section LICENSE - -The MIT License (MIT) - -Copyright (c) 2014 Woong Gyu La - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -@section DESCRIPTION - -A IocpTcpClient Class. - -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using System.Net; -using System.Net.Sockets; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.IO; -using System.Threading; -using System.Diagnostics; +/*! +@file IocpTcpClient.cs +@author Woong Gyu La a.k.a Chris. + +@date April 01, 2014 +@brief IocpTcpClient Interface +@version 2.0 + +@section LICENSE + +The MIT License (MIT) + +Copyright (c) 2014 Woong Gyu La + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@section DESCRIPTION + +A IocpTcpClient Class. + +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Net; +using System.Net.Sockets; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.IO; +using System.Threading; +using System.Diagnostics; using EpLibrary.cs; -using System.Threading.Tasks; - -namespace EpServerEngine.cs -{ - /// - /// A IOCP TCP Client class. - /// - public sealed class IocpTcpClient : ThreadEx, INetworkClient, IDisposable - { - /// - /// Actual TCP client - /// - private TcpClient m_client=new TcpClient(); - /// - /// client options - /// - private ClientOps m_clientOps = null; - - /// - /// general lock - /// - private Object m_generalLock = new Object(); - - /// - /// send lock - /// - private Object m_sendLock = new Object(); - /// - /// send queue lock - /// - private Object m_sendQueueLock = new Object(); - /// - /// send queue - /// - private Queue m_sendQueue = new Queue(); - - /// - /// callback object - /// - private INetworkClientCallback m_callBackObj=null; - /// - /// hostname - /// - private String m_hostName; - /// - /// port - /// - private String m_port; - /// - /// flag for nodelay - /// - private bool m_noDelay; - /// - /// connection time out in millisecond - /// +using System.Threading.Tasks; + +namespace EpServerEngine.cs +{ + /// + /// A IOCP TCP Client class. + /// + public sealed class IocpTcpClient : ThreadEx, INetworkClient, IDisposable + { + /// + /// Actual TCP client + /// + private TcpClient m_client=new TcpClient(); + /// + /// client options + /// + private ClientOps m_clientOps = null; + + /// + /// general lock + /// + private Object m_generalLock = new Object(); + + /// + /// send lock + /// + private Object m_sendLock = new Object(); + /// + /// send queue lock + /// + private Object m_sendQueueLock = new Object(); + /// + /// send queue + /// + private Queue m_sendQueue = new Queue(); + + /// + /// callback object + /// + private INetworkClientCallback m_callBackObj=null; + /// + /// hostname + /// + private String m_hostName; + /// + /// port + /// + private String m_port; + /// + /// flag for nodelay + /// + private bool m_noDelay; + /// + /// connection time out in millisecond + /// private int m_connectionTimeOut; - - /// - /// connection time-out event - /// - private EventEx m_timeOutEvent = new EventEx(false, EventResetMode.AutoReset); - /// - /// send event - /// - private EventEx m_sendEvent = new EventEx(); - - - /// - /// receive message size packet - /// - private Packet m_recvSizePacket = new Packet(null, 0, Preamble.SIZE_PACKET_LENGTH); - - /// - /// flag for connection check - /// + + /// + /// connection time-out event + /// + private EventEx m_timeOutEvent = new EventEx(false, EventResetMode.AutoReset); + /// + /// send event + /// + private EventEx m_sendEvent = new EventEx(); + + + /// + /// receive message size packet + /// + private Packet m_recvSizePacket = new Packet(null, 0, Preamble.SIZE_PACKET_LENGTH); + + /// + /// flag for connection check + /// private bool m_isConnected = false; /// @@ -235,32 +235,32 @@ public OnClientDisconnectDelegate OnDisconnect } } } - - /// - /// Default constructor - /// - public IocpTcpClient():base() - { - - } - - /// - /// Default copy constructor - /// - /// the object to copy from - public IocpTcpClient(IocpTcpClient b) - : base(b) - { - m_clientOps = b.m_clientOps; - } - ~IocpTcpClient() + + /// + /// Default constructor + /// + public IocpTcpClient():base() + { + + } + + /// + /// Default copy constructor + /// + /// the object to copy from + public IocpTcpClient(IocpTcpClient b) + : base(b) + { + m_clientOps = b.m_clientOps; + } + ~IocpTcpClient() { - Dispose(false); - } - - /// - /// Return hostname - /// + Dispose(false); + } + + /// + /// Return hostname + /// /// hostname public String HostName { @@ -278,13 +278,13 @@ private set m_hostName = value; } } - } - - /// - /// Return port - /// - /// port - public String Port + } + + /// + /// Return port + /// + /// port + public String Port { get { @@ -299,7 +299,7 @@ private set { m_port = value; } - } + } } /// @@ -378,45 +378,49 @@ public INetworkClientCallback CallBackObj } } } - } - /// - /// Callback Exception class - /// - [Serializable] - private class CallbackException : Exception - { - /// - /// Default constructor - /// - public CallbackException() - : base() - { - - } - /// - /// Default constructor - /// - /// message for exception - public CallbackException(String message) - : base(message) - { - - } - } - /// - /// Make the connection to the server and start receiving - /// - protected override void execute() - { - ConnectStatus status = ConnectStatus.SUCCESS; - try + } + /// + /// Callback Exception class + /// + [Serializable] + private class CallbackException : Exception + { + /// + /// Default constructor + /// + public CallbackException() + : base() + { + + } + /// + /// Default constructor + /// + /// message for exception + public CallbackException(String message) + : base(message) + { + + } + } + /// + /// Make the connection to the server and start receiving + /// + protected override void execute() + { + ConnectStatus status = ConnectStatus.SUCCESS; + try { lock (m_generalLock) { if (IsConnectionAlive) { status = ConnectStatus.FAIL_ALREADY_CONNECTED; - throw new CallbackException(); + new Task(delegate () + { + OnConnected(this, status); + }).Start(); + return; } CallBackObj = m_clientOps.CallBackObj; @@ -425,7 +429,6 @@ protected override void execute() NoDelay = m_clientOps.NoDelay; ConnectionTimeOut = m_clientOps.ConnectionTimeOut; - if (HostName == null || HostName.Length == 0) { HostName = ServerConf.DEFAULT_HOSTNAME; @@ -445,14 +448,17 @@ protected override void execute() if (!m_client.Connected) { status = ConnectStatus.FAIL_SOCKET_ERROR; - throw new CallbackException(); + new Task(delegate () + { + OnConnected(this, status); + }).Start(); + return; } IsConnectionAlive = true; - Task t = new Task(delegate() + new Task(delegate() { OnConnected(this, ConnectStatus.SUCCESS); - }); - t.Start(); + }).Start(); } @@ -460,8 +466,11 @@ protected override void execute() { try { - m_client.Client.Shutdown(SocketShutdown.Both); - //Client.Client.Disconnect(true); + if (m_client.Client.Connected) + { + m_client.Client.Shutdown(SocketShutdown.Both); + //Client.Client.Disconnect(true); + } } catch (Exception ex) { @@ -469,74 +478,76 @@ protected override void execute() } m_client.Close(); status = ConnectStatus.FAIL_TIME_OUT; - throw new CallbackException(); + Task t = new Task(delegate () + { + OnConnected(this, status); + }); + t.Start(); + return; } - } - } - catch(CallbackException) - { - Task t = new Task(delegate() - { - OnConnected(this, status); - }); - t.Start(); - return; - } - catch (Exception ex) - { + } + } + catch (Exception ex) + { Console.WriteLine(ex.Message + " >" + ex.StackTrace); - Task t = new Task(delegate() - { - OnConnected(this, ConnectStatus.FAIL_SOCKET_ERROR); - }); - t.Start(); - return; - } - startReceive(); - - } - /// - /// Connect to the server with given options - /// - /// options for client - public void Connect(ClientOps ops) + Task t = new Task(delegate() + { + OnConnected(this, ConnectStatus.FAIL_SOCKET_ERROR); + }); + t.Start(); + return; + } + startReceive(); + + } + /// + /// Connect to the server with given options + /// + /// options for client + public void Connect(ClientOps ops) { - if (ops == null) - ops = ClientOps.defaultClientOps; -// if (ops.CallBackObj == null) -// throw new NullReferenceException("callBackObj is null!"); - lock (m_generalLock) - { - m_clientOps = ops; - } - Start(); - - } - - /// - /// Connection callback function - /// - /// result - private static void onConnected(IAsyncResult result) - { - IocpTcpClient tcpclient = result.AsyncState as IocpTcpClient; - - try { tcpclient.m_client.Client.EndConnect(result); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - tcpclient.m_timeOutEvent.SetEvent(); - return; - } - tcpclient.m_timeOutEvent.SetEvent(); - return; - - } - - /// - /// Disconnect from the server - /// - public void Disconnect() + if (ops == null) + ops = ClientOps.defaultClientOps; +// if (ops.CallBackObj == null) +// throw new NullReferenceException("callBackObj is null!"); + lock (m_generalLock) + { + m_clientOps = ops; + } + Start(); + + } + + /// + /// Connection callback function + /// + /// result + private static void onConnected(IAsyncResult result) + { + IocpTcpClient tcpclient = result.AsyncState as IocpTcpClient; + + try + { + if (tcpclient.m_client.Client != null) + { + tcpclient.m_client.Client.EndConnect(result); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + tcpclient.m_timeOutEvent.SetEvent(); + return; + } + tcpclient.m_timeOutEvent.SetEvent(); + return; + + } + + /// + /// Disconnect from the server + /// + public void Disconnect() { lock (m_generalLock) { @@ -553,33 +564,30 @@ public void Disconnect() } m_client.Close(); IsConnectionAlive = false; - } - - lock (m_sendQueueLock) - { - m_sendQueue.Clear(); - } + } + + lock (m_sendQueueLock) + { + m_sendQueue.Clear(); + } + + Task t = new Task(delegate() + { + OnDisconnect(this); + }); + t.Start(); - Task t = new Task(delegate() - { - OnDisconnect(this); - }); - t.Start(); - - } - - /// - /// Check if the connection is alive - /// - /// true if connection is alive, otherwise false - public bool IsConnectionAlive + } + + /// + /// Check if the connection is alive + /// + /// true if connection is alive, otherwise false + public bool IsConnectionAlive { get { - lock (m_generalLock) - { - return m_isConnected; - } + return m_isConnected; } private set { @@ -587,341 +595,341 @@ private set { m_isConnected = value; } - } - - } - - /// - /// Send given packet to the server - /// - /// packet to send - public void Send(Packet packet) - { - - if (!IsConnectionAlive) + } + + } + + /// + /// Send given packet to the server + /// + /// packet to send + public void Send(Packet packet) + { + + if (!IsConnectionAlive) { - Task t = new Task(delegate() + Task t = new Task(delegate() { - OnSent(this, SendStatus.FAIL_NOT_CONNECTED, packet); - }); - t.Start(); - - return; - } - if (packet.PacketByteSize <= 0) + OnSent(this, SendStatus.FAIL_NOT_CONNECTED, packet); + }); + t.Start(); + + return; + } + if (packet.PacketByteSize <= 0) { - Task t = new Task(delegate() - { - OnSent(this, SendStatus.FAIL_INVALID_PACKET, packet); - }); - t.Start(); - return; - } - - lock (m_sendLock) - { - Packet sendSizePacket = new Packet(null,0, Preamble.SIZE_PACKET_LENGTH, false); - PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this, packet); + Task t = new Task(delegate() + { + OnSent(this, SendStatus.FAIL_INVALID_PACKET, packet); + }); + t.Start(); + return; + } + + lock (m_sendLock) + { + Packet sendSizePacket = new Packet(null,0, Preamble.SIZE_PACKET_LENGTH, false); + PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this, packet); //sendSizePacket.SetPacket(BitConverter.GetBytes(packet.GetPacketByteSize()), ServerConf.SIZE_PACKET_LENGTH); - sendSizePacket.SetPacket(Preamble.ToPreamblePacket(packet.PacketByteSize), 0, Preamble.SIZE_PACKET_LENGTH); - if (m_sendEvent.TryLock()) - { - try { m_client.Client.BeginSend(sendSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } - catch (Exception ex) - { + sendSizePacket.SetPacket(Preamble.ToPreamblePacket(packet.PacketByteSize), 0, Preamble.SIZE_PACKET_LENGTH); + if (m_sendEvent.TryLock()) + { + try { m_client.Client.BeginSend(sendSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } + catch (Exception ex) + { Console.WriteLine(ex.Message + " >" + ex.StackTrace); - OnSent(this, SendStatus.FAIL_SOCKET_ERROR, packet); - Disconnect(); - return; - } - } - else - { - lock (m_sendQueueLock) - { - m_sendQueue.Enqueue(transport); - } - } - } - - - } - /// - /// Send given data to the server - /// - /// data in byte array - /// offset in bytes - /// data size in bytes - public void Send(byte[] data, int offset, int dataSize) + OnSent(this, SendStatus.FAIL_SOCKET_ERROR, packet); + Disconnect(); + return; + } + } + else + { + lock (m_sendQueueLock) + { + m_sendQueue.Enqueue(transport); + } + } + } + + + } + /// + /// Send given data to the server + /// + /// data in byte array + /// offset in bytes + /// data size in bytes + public void Send(byte[] data, int offset, int dataSize) { - Packet sendPacket=null; - sendPacket = new Packet(data,offset, dataSize, false); -// byte[] packet = new byte[dataSize]; -// MemoryStream stream = new MemoryStream(packet); + Packet sendPacket=null; + sendPacket = new Packet(data,offset, dataSize, false); +// byte[] packet = new byte[dataSize]; +// MemoryStream stream = new MemoryStream(packet); // stream.Write(data, offset, dataSize); - // Packet sendPacket = new Packet(packet,0, packet.Count(), false); - - Send(sendPacket); - - } - - /// - /// Send given data to the server - /// - /// data in byte array - public void Send(byte[] data) - { - Send(data, 0, data.Count()); - } - - /// - /// Enumerator for packet type - /// - private enum PacketType - { - /// - /// Send type - /// - SIZE = 0, - /// - /// Receive type - /// - DATA - } - - /// - /// Packet Transporter class - /// - private class PacketTransporter - { - /// - /// packet to transport - /// - public Packet m_packet; - /// - /// data packet for send - /// - public Packet m_dataPacket; - /// - /// offset - /// - public int m_offset; - /// - /// packet size in byte - /// - public int m_size; - /// - /// client - /// - public IocpTcpClient m_iocpTcpClient; - /// - /// packet type - /// - public PacketType m_packetType; - /// - /// Default constructor - /// - /// packet type - /// packet - /// offset - /// size of packet in byte - /// client - /// data packet for send - public PacketTransporter(PacketType packetType,Packet packet, int offset, int size, IocpTcpClient iocpTcpClient,Packet dataPacket=null) - { - m_packetType = packetType; - m_packet = packet; - m_offset = offset; - m_size = size; - m_iocpTcpClient = iocpTcpClient; + // Packet sendPacket = new Packet(packet,0, packet.Count(), false); + + Send(sendPacket); + + } + + /// + /// Send given data to the server + /// + /// data in byte array + public void Send(byte[] data) + { + Send(data, 0, data.Count()); + } + + /// + /// Enumerator for packet type + /// + private enum PacketType + { + /// + /// Send type + /// + SIZE = 0, + /// + /// Receive type + /// + DATA + } + + /// + /// Packet Transporter class + /// + private class PacketTransporter + { + /// + /// packet to transport + /// + public Packet m_packet; + /// + /// data packet for send + /// + public Packet m_dataPacket; + /// + /// offset + /// + public int m_offset; + /// + /// packet size in byte + /// + public int m_size; + /// + /// client + /// + public IocpTcpClient m_iocpTcpClient; + /// + /// packet type + /// + public PacketType m_packetType; + /// + /// Default constructor + /// + /// packet type + /// packet + /// offset + /// size of packet in byte + /// client + /// data packet for send + public PacketTransporter(PacketType packetType,Packet packet, int offset, int size, IocpTcpClient iocpTcpClient,Packet dataPacket=null) + { + m_packetType = packetType; + m_packet = packet; + m_offset = offset; + m_size = size; + m_iocpTcpClient = iocpTcpClient; m_dataPacket = dataPacket; - } - } - /// - /// Start to receive packet from the server - /// - private void startReceive() - { - PacketTransporter transport = new PacketTransporter(PacketType.SIZE, m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this); - try { m_client.Client.BeginReceive(m_recvSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - Disconnect(); return; - } - - } - - /// - /// Receive callback function - /// - /// result - private static void onReceived(IAsyncResult result) - { - PacketTransporter transport = result.AsyncState as PacketTransporter; - Socket socket = transport.m_iocpTcpClient.m_client.Client; - - int readSize=0; - try { readSize = socket.EndReceive(result); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; - } - if (readSize == 0) - { - transport.m_iocpTcpClient.Disconnect(); - return; - } - if (readSize < transport.m_size) - { - transport.m_offset = transport.m_offset + readSize; - transport.m_size = transport.m_size - readSize; - try{socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport);} - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; - } - } - else - { - if (transport.m_packetType == PacketType.SIZE) - { - //int shouldReceive = BitConverter.ToInt32(transport.m_packet.PacketRaw, 0); - int shouldReceive = Preamble.ToShouldReceive(transport.m_packet.PacketRaw); - - // preamble packet is corrupted - // try to receive another byte to check preamble - if (shouldReceive < 0) - { - int preambleOffset = Preamble.CheckPreamble(transport.m_packet.PacketRaw); - // set offset to length - preamble offset - transport.m_offset = transport.m_packet.PacketByteSize - preambleOffset; - // need to receive as much as preamble offset - transport.m_size = preambleOffset; - try - { + } + } + /// + /// Start to receive packet from the server + /// + private void startReceive() + { + PacketTransporter transport = new PacketTransporter(PacketType.SIZE, m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this); + try { m_client.Client.BeginReceive(m_recvSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + Disconnect(); return; + } + + } + + /// + /// Receive callback function + /// + /// result + private static void onReceived(IAsyncResult result) + { + PacketTransporter transport = result.AsyncState as PacketTransporter; + Socket socket = transport.m_iocpTcpClient.m_client.Client; + + int readSize=0; + try { readSize = socket.EndReceive(result); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; + } + if (readSize == 0) + { + transport.m_iocpTcpClient.Disconnect(); + return; + } + if (readSize < transport.m_size) + { + transport.m_offset = transport.m_offset + readSize; + transport.m_size = transport.m_size - readSize; + try{socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport);} + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; + } + } + else + { + if (transport.m_packetType == PacketType.SIZE) + { + //int shouldReceive = BitConverter.ToInt32(transport.m_packet.PacketRaw, 0); + int shouldReceive = Preamble.ToShouldReceive(transport.m_packet.PacketRaw); + + // preamble packet is corrupted + // try to receive another byte to check preamble + if (shouldReceive < 0) + { + int preambleOffset = Preamble.CheckPreamble(transport.m_packet.PacketRaw); + // set offset to length - preamble offset + transport.m_offset = transport.m_packet.PacketByteSize - preambleOffset; + // need to receive as much as preamble offset + transport.m_size = preambleOffset; + try + { // shift to left by preamble offset - Buffer.BlockCopy(transport.m_packet.PacketRaw, preambleOffset, transport.m_packet.PacketRaw, 0, transport.m_packet.PacketByteSize - preambleOffset); + Buffer.BlockCopy(transport.m_packet.PacketRaw, preambleOffset, transport.m_packet.PacketRaw, 0, transport.m_packet.PacketByteSize - preambleOffset); // receive rest of bytes at the end - socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; - } - return; + socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), transport); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; + } + return; } - Packet recvPacket = new Packet(null, 0, shouldReceive); + Packet recvPacket = new Packet(null, 0, shouldReceive); PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, shouldReceive, transport.m_iocpTcpClient); - try { socket.BeginReceive(recvPacket.PacketRaw, 0, shouldReceive, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), dataTransport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; - } - } - else - { + try { socket.BeginReceive(recvPacket.PacketRaw, 0, shouldReceive, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), dataTransport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; + } + } + else + { PacketTransporter sizeTransport = new PacketTransporter(PacketType.SIZE, transport.m_iocpTcpClient.m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, transport.m_iocpTcpClient); - try { socket.BeginReceive(sizeTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), sizeTransport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; + try { socket.BeginReceive(sizeTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onReceived), sizeTransport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; } - transport.m_iocpTcpClient.OnReceived(transport.m_iocpTcpClient, transport.m_packet); - } - } - } - /// - /// Send callback function - /// - /// result - private static void onSent(IAsyncResult result) - { - PacketTransporter transport = result.AsyncState as PacketTransporter; - Socket socket = transport.m_iocpTcpClient.m_client.Client; - - int sentSize=0; - try { sentSize = socket.EndSend(result); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.OnReceived(transport.m_iocpTcpClient, transport.m_packet); + } + } + } + /// + /// Send callback function + /// + /// result + private static void onSent(IAsyncResult result) + { + PacketTransporter transport = result.AsyncState as PacketTransporter; + Socket socket = transport.m_iocpTcpClient.m_client.Client; + + int sentSize=0; + try { sentSize = socket.EndSend(result); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; } - if (sentSize == 0) - { + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; } + if (sentSize == 0) + { transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_CONNECTION_CLOSING, transport.m_dataPacket); - return; - } - if (sentSize < transport.m_size) - { - transport.m_offset = transport.m_offset + sentSize; - transport.m_size = transport.m_size - sentSize; - try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_CONNECTION_CLOSING, transport.m_dataPacket); + return; + } + if (sentSize < transport.m_size) + { + transport.m_offset = transport.m_offset + sentSize; + transport.m_size = transport.m_size - sentSize; + try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; - } - } - else - { - if (transport.m_packetType == PacketType.SIZE) - { + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; + } + } + else + { + if (transport.m_packetType == PacketType.SIZE) + { transport.m_packet = transport.m_dataPacket; - transport.m_offset = transport.m_dataPacket.PacketOffset; ; - transport.m_packetType = PacketType.DATA; + transport.m_offset = transport.m_dataPacket.PacketOffset; ; + transport.m_packetType = PacketType.DATA; transport.m_size = transport.m_dataPacket.PacketByteSize; - try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; - } - } - else - { - PacketTransporter delayedTransport = null; - lock (transport.m_iocpTcpClient.m_sendQueueLock) - { - Queue sendQueue = transport.m_iocpTcpClient.m_sendQueue; - if (sendQueue.Count > 0) - { - delayedTransport = sendQueue.Dequeue(); - } - } - if (delayedTransport != null) - { - try { socket.BeginSend(delayedTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), delayedTransport); } - catch (Exception ex) - { + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; + } + } + else + { + PacketTransporter delayedTransport = null; + lock (transport.m_iocpTcpClient.m_sendQueueLock) + { + Queue sendQueue = transport.m_iocpTcpClient.m_sendQueue; + if (sendQueue.Count > 0) + { + delayedTransport = sendQueue.Dequeue(); + } + } + if (delayedTransport != null) + { + try { socket.BeginSend(delayedTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpClient.onSent), delayedTransport); } + catch (Exception ex) + { Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); delayedTransport.m_iocpTcpClient.Disconnect(); - delayedTransport.m_iocpTcpClient.OnSent(delayedTransport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, delayedTransport.m_dataPacket); - return; - } - } - else - { - transport.m_iocpTcpClient.m_sendEvent.Unlock(); + delayedTransport.m_iocpTcpClient.OnSent(delayedTransport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, delayedTransport.m_dataPacket); + return; + } } - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); - } - } - + else + { + transport.m_iocpTcpClient.m_sendEvent.Unlock(); + } + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); + } + } + } /// @@ -977,7 +985,7 @@ private void Dispose(bool isDisposing) { this.IsDisposed = true; } - } - - } -} + } + + } +} diff --git a/EpServerEngine.cs/EpServerEngine.cs/ServerSide/IOCP/IocpTcpSocket.cs b/EpServerEngine.cs/EpServerEngine.cs/ServerSide/IOCP/IocpTcpSocket.cs index ae17cc1..2693359 100644 --- a/EpServerEngine.cs/EpServerEngine.cs/ServerSide/IOCP/IocpTcpSocket.cs +++ b/EpServerEngine.cs/EpServerEngine.cs/ServerSide/IOCP/IocpTcpSocket.cs @@ -1,111 +1,111 @@ -/*! -@file IocpTcpSocket.cs -@author Woong Gyu La a.k.a Chris. - -@date April 01, 2014 -@brief IocpTcpSocket Interface -@version 2.0 - -@section LICENSE - -The MIT License (MIT) - -Copyright (c) 2014 Woong Gyu La - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -@section DESCRIPTION - -A IocpTcpSocket Class. - -*/ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using System.Net; -using System.Net.Sockets; -using System.IO; -using System.Threading; -using System.Diagnostics; +/*! +@file IocpTcpSocket.cs +@author Woong Gyu La a.k.a Chris. + +@date April 01, 2014 +@brief IocpTcpSocket Interface +@version 2.0 + +@section LICENSE + +The MIT License (MIT) + +Copyright (c) 2014 Woong Gyu La + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +@section DESCRIPTION + +A IocpTcpSocket Class. + +*/ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Diagnostics; using EpLibrary.cs; -using System.Threading.Tasks; - -namespace EpServerEngine.cs -{ - /// - /// IOCP TCP Socket class - /// - public sealed class IocpTcpSocket:ThreadEx,INetworkSocket, IDisposable - { - /// - /// actual client - /// - private TcpClient m_client=null; - /// - /// managing server - /// - private INetworkServer m_server = null; - /// - /// IP information - /// - private IPInfo m_ipInfo; - /// - /// general lock - /// - private Object m_generalLock = new Object(); - /// - /// send lock - /// - private Object m_sendLock = new Object(); - /// - /// send queue lock - /// +using System.Threading.Tasks; + +namespace EpServerEngine.cs +{ + /// + /// IOCP TCP Socket class + /// + public sealed class IocpTcpSocket:ThreadEx,INetworkSocket, IDisposable + { + /// + /// actual client + /// + private TcpClient m_client=null; + /// + /// managing server + /// + private INetworkServer m_server = null; + /// + /// IP information + /// + private IPInfo m_ipInfo; + /// + /// general lock + /// + private Object m_generalLock = new Object(); + /// + /// send lock + /// + private Object m_sendLock = new Object(); + /// + /// send queue lock + /// private Object m_sendQueueLock = new Object(); /// /// client socket room lock /// - private Object m_roomLock = new Object(); - - /// - /// send queue - /// - private Queue m_sendQueue = new Queue(); - /// - /// callback object - /// - private INetworkSocketCallback m_callBackObj=null; - - /// - /// send event - /// - private EventEx m_sendEvent = new EventEx(); - - /// - /// receive size packet - /// - private Packet m_recvSizePacket = new Packet(null,0, Preamble.SIZE_PACKET_LENGTH); - - /// - /// flag for connection check - /// + private Object m_roomLock = new Object(); + + /// + /// send queue + /// + private Queue m_sendQueue = new Queue(); + /// + /// callback object + /// + private INetworkSocketCallback m_callBackObj=null; + + /// + /// send event + /// + private EventEx m_sendEvent = new EventEx(); + + /// + /// receive size packet + /// + private Packet m_recvSizePacket = new Packet(null,0, Preamble.SIZE_PACKET_LENGTH); + + /// + /// flag for connection check + /// private bool m_isConnected = false; /// @@ -228,41 +228,41 @@ public OnSocketDisconnectDelegate OnDisconnect /// /// room list /// - private Dictionary m_roomMap = new Dictionary(); - - /// - /// Default constructor - /// - /// client - /// managing server - public IocpTcpSocket(TcpClient client, INetworkServer server):base() - { - m_client=client; + private Dictionary m_roomMap = new Dictionary(); + + /// + /// Default constructor + /// + /// client + /// managing server + public IocpTcpSocket(TcpClient client, INetworkServer server):base() + { + m_client=client; m_server = server; - NoDelay = server.NoDelay; - IPEndPoint remoteIpEndPoint = m_client.Client.RemoteEndPoint as IPEndPoint; - IPEndPoint localIpEndPoint = m_client.Client.LocalEndPoint as IPEndPoint; - if (remoteIpEndPoint != null) - { - String socketHostName = remoteIpEndPoint.Address.ToString(); - m_ipInfo = new IPInfo(socketHostName, remoteIpEndPoint, IPEndPointType.REMOTE); - } - else if (localIpEndPoint != null) - { - String socketHostName = localIpEndPoint.Address.ToString(); - m_ipInfo = new IPInfo(socketHostName, localIpEndPoint, IPEndPointType.LOCAL); - } - - } - - ~IocpTcpSocket() - { - Dispose(false); - } - - /// - /// Get IP information - /// + NoDelay = server.NoDelay; + IPEndPoint remoteIpEndPoint = m_client.Client.RemoteEndPoint as IPEndPoint; + IPEndPoint localIpEndPoint = m_client.Client.LocalEndPoint as IPEndPoint; + if (remoteIpEndPoint != null) + { + String socketHostName = remoteIpEndPoint.Address.ToString(); + m_ipInfo = new IPInfo(socketHostName, remoteIpEndPoint, IPEndPointType.REMOTE); + } + else if (localIpEndPoint != null) + { + String socketHostName = localIpEndPoint.Address.ToString(); + m_ipInfo = new IPInfo(socketHostName, localIpEndPoint, IPEndPointType.LOCAL); + } + + } + + ~IocpTcpSocket() + { + Dispose(false); + } + + /// + /// Get IP information + /// /// IP information public IPInfo IPInfo { @@ -273,11 +273,11 @@ public IPInfo IPInfo return m_ipInfo; } } - } - - /// - /// Get managing server - /// + } + + /// + /// Get managing server + /// /// managing server public INetworkServer Server { @@ -344,22 +344,22 @@ public INetworkSocketCallback CallBackObj } } } - } - - /// - /// Start the new connection, and inform the callback object, that the new connection is made - /// - protected override void execute() + } + + /// + /// Start the new connection, and inform the callback object, that the new connection is made + /// + protected override void execute() { - IsConnectionAlive = true; + IsConnectionAlive = true; startReceive(); - OnNewConnection(this); - } - - /// - /// Disconnect the client socket - /// - public void Disconnect() + OnNewConnection(this); + } + + /// + /// Disconnect the client socket + /// + public void Disconnect() { lock (m_generalLock) { @@ -387,23 +387,23 @@ public void Disconnect() lock (m_roomLock) { m_roomMap.Clear(); - } - - lock (m_sendQueueLock) - { - m_sendQueue.Clear(); - } - Task t = new Task(delegate() - { - OnDisconnect(this); - }); - t.Start(); - - } - - /// - /// Check if the connection is alive - /// + } + + lock (m_sendQueueLock) + { + m_sendQueue.Clear(); + } + Task t = new Task(delegate() + { + OnDisconnect(this); + }); + t.Start(); + + } + + /// + /// Check if the connection is alive + /// /// true if connection is alive, otherwise false public bool IsConnectionAlive { @@ -430,85 +430,85 @@ private set m_isConnected = value; } } - } - - /// - /// Send given packet to the client - /// - /// the packet to send - public void Send(Packet packet) - { - if (!IsConnectionAlive) + } + + /// + /// Send given packet to the client + /// + /// the packet to send + public void Send(Packet packet) + { + if (!IsConnectionAlive) { - Task t = new Task(delegate() + Task t = new Task(delegate() { OnSent(this, SendStatus.FAIL_NOT_CONNECTED, packet); - }); - t.Start(); - - return; - } - if (packet.PacketByteSize <= 0) - { - Task t = new Task(delegate() - { - OnSent(this, SendStatus.FAIL_INVALID_PACKET, packet); - }); - t.Start(); - - return; - } - - lock (m_sendLock) - { - Packet sendSizePacket = new Packet(null, 0, Preamble.SIZE_PACKET_LENGTH, false); - PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this, packet); - + }); + t.Start(); + + return; + } + if (packet.PacketByteSize <= 0) + { + Task t = new Task(delegate() + { + OnSent(this, SendStatus.FAIL_INVALID_PACKET, packet); + }); + t.Start(); + + return; + } + + lock (m_sendLock) + { + Packet sendSizePacket = new Packet(null, 0, Preamble.SIZE_PACKET_LENGTH, false); + PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this, packet); + //sendSizePacket.SetPacket(BitConverter.GetBytes(packet.GetPacketByteSize()), 4); - sendSizePacket.SetPacket(Preamble.ToPreamblePacket(packet.PacketByteSize), 0, Preamble.SIZE_PACKET_LENGTH); - if (m_sendEvent.TryLock()) - { - try { m_client.Client.BeginSend(sendSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - Disconnect(); - return; - } - } - else - { - lock (m_sendQueueLock) - { - m_sendQueue.Enqueue(transport); - } - } - } - } - - /// - /// Send given data to the client - /// - /// data in byte array - /// offset in bytes - /// data size in bytes - public void Send(byte[] data, int offset, int dataSize) - { - Packet sendPacket = new Packet(data,offset, dataSize, false); -// byte[] packet = new byte[dataSize]; -// MemoryStream stream = new MemoryStream(packet); + sendSizePacket.SetPacket(Preamble.ToPreamblePacket(packet.PacketByteSize), 0, Preamble.SIZE_PACKET_LENGTH); + if (m_sendEvent.TryLock()) + { + try { m_client.Client.BeginSend(sendSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + Disconnect(); + return; + } + } + else + { + lock (m_sendQueueLock) + { + m_sendQueue.Enqueue(transport); + } + } + } + } + + /// + /// Send given data to the client + /// + /// data in byte array + /// offset in bytes + /// data size in bytes + public void Send(byte[] data, int offset, int dataSize) + { + Packet sendPacket = new Packet(data,offset, dataSize, false); +// byte[] packet = new byte[dataSize]; +// MemoryStream stream = new MemoryStream(packet); // stream.Write(data, offset, dataSize); - // Packet sendPacket = new Packet(packet,0, packet.Count(), false); - Send(sendPacket); - } - - /// - /// Send given data to the client - /// - /// data in byte array - public void Send(byte[] data) - { - Send(data, 0, data.Count()); + // Packet sendPacket = new Packet(packet,0, packet.Count(), false); + Send(sendPacket); + } + + /// + /// Send given data to the client + /// + /// data in byte array + public void Send(byte[] data) + { + Send(data, 0, data.Count()); } /// @@ -538,262 +538,262 @@ public void Broadcast(byte[] data, int offset, int dataSize) public void Broadcast(byte[] data) { ((IocpTcpServer)Server).Broadcast(this, data); - } - - /// - /// Enumerator for packet type - /// - private enum PacketType - { - /// - /// Send type - /// - SIZE = 0, - /// - /// Receive type - /// - DATA - } - /// - /// Packet Transporter class - /// - private class PacketTransporter - { - /// - /// packet to transport - /// - public Packet m_packet; - /// - /// data packet for send - /// - public Packet m_dataPacket; - /// - /// offset - /// - public int m_offset; - /// - /// packet size in byte - /// - public int m_size; - /// - /// client socket - /// - public IocpTcpSocket m_iocpTcpClient; - /// - /// packet type - /// - public PacketType m_packetType; - /// - /// Default constructor - /// - /// packet type - /// packet - /// offset - /// size of packet in byte - /// client socket - /// data packet for send - public PacketTransporter(PacketType packetType, Packet packet, int offset, int size, IocpTcpSocket iocpTcpClient, Packet dataPacket = null) - { - m_packetType = packetType; - m_packet = packet; - m_offset = offset; - m_size = size; - m_iocpTcpClient = iocpTcpClient; - m_dataPacket = dataPacket; - } - } - /// - /// Start to receive packet from the server - /// - private void startReceive() - { - PacketTransporter transport = new PacketTransporter(PacketType.SIZE, m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this); - try { m_client.Client.BeginReceive(m_recvSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - Disconnect(); - return; - } - - } - - /// - /// Receive callback function - /// - /// result - private static void onReceived(IAsyncResult result) - { - PacketTransporter transport = result.AsyncState as PacketTransporter; - Socket socket = transport.m_iocpTcpClient.m_client.Client; - - int readSize=0; - try { - if(socket!=null) - readSize = socket.EndReceive(result); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); - return; - } - if (readSize == 0) - { - transport.m_iocpTcpClient.Disconnect(); - return; - } - if (readSize < transport.m_size) - { - transport.m_offset = transport.m_offset + readSize; - transport.m_size = transport.m_size - readSize; - try { socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); - return; - } - } - else - { - if (transport.m_packetType == PacketType.SIZE) - { - //int shouldReceive = BitConverter.ToInt32(transport.m_packet.PacketRaw, 0); - int shouldReceive = Preamble.ToShouldReceive(transport.m_packet.PacketRaw); - - // preamble packet is corrupted - // try to receive another byte to check preamble - if (shouldReceive < 0) - { - int preambleOffset = Preamble.CheckPreamble(transport.m_packet.PacketRaw); - // set offset to length - preamble offset - transport.m_offset = transport.m_packet.PacketByteSize - preambleOffset; - // need to receive as much as preamble offset - transport.m_size = preambleOffset; - try - { - // shift to left by preamble offset - Buffer.BlockCopy(transport.m_packet.PacketRaw, preambleOffset, transport.m_packet.PacketRaw, 0, transport.m_packet.PacketByteSize - preambleOffset); - // receive rest of bytes at the end - socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); return; - } - return; + } + + /// + /// Enumerator for packet type + /// + private enum PacketType + { + /// + /// Send type + /// + SIZE = 0, + /// + /// Receive type + /// + DATA + } + /// + /// Packet Transporter class + /// + private class PacketTransporter + { + /// + /// packet to transport + /// + public Packet m_packet; + /// + /// data packet for send + /// + public Packet m_dataPacket; + /// + /// offset + /// + public int m_offset; + /// + /// packet size in byte + /// + public int m_size; + /// + /// client socket + /// + public IocpTcpSocket m_iocpTcpClient; + /// + /// packet type + /// + public PacketType m_packetType; + /// + /// Default constructor + /// + /// packet type + /// packet + /// offset + /// size of packet in byte + /// client socket + /// data packet for send + public PacketTransporter(PacketType packetType, Packet packet, int offset, int size, IocpTcpSocket iocpTcpClient, Packet dataPacket = null) + { + m_packetType = packetType; + m_packet = packet; + m_offset = offset; + m_size = size; + m_iocpTcpClient = iocpTcpClient; + m_dataPacket = dataPacket; + } + } + /// + /// Start to receive packet from the server + /// + private void startReceive() + { + PacketTransporter transport = new PacketTransporter(PacketType.SIZE, m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, this); + try { m_client.Client.BeginReceive(m_recvSizePacket.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + Disconnect(); + return; + } + + } + + /// + /// Receive callback function + /// + /// result + private static void onReceived(IAsyncResult result) + { + PacketTransporter transport = result.AsyncState as PacketTransporter; + Socket socket = transport.m_iocpTcpClient.m_client.Client; + + int readSize=0; + try { + if(socket!=null) + readSize = socket.EndReceive(result); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); + return; + } + if (readSize == 0) + { + transport.m_iocpTcpClient.Disconnect(); + return; + } + if (readSize < transport.m_size) + { + transport.m_offset = transport.m_offset + readSize; + transport.m_size = transport.m_size - readSize; + try { socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); + return; + } + } + else + { + if (transport.m_packetType == PacketType.SIZE) + { + //int shouldReceive = BitConverter.ToInt32(transport.m_packet.PacketRaw, 0); + int shouldReceive = Preamble.ToShouldReceive(transport.m_packet.PacketRaw); + + // preamble packet is corrupted + // try to receive another byte to check preamble + if (shouldReceive < 0) + { + int preambleOffset = Preamble.CheckPreamble(transport.m_packet.PacketRaw); + // set offset to length - preamble offset + transport.m_offset = transport.m_packet.PacketByteSize - preambleOffset; + // need to receive as much as preamble offset + transport.m_size = preambleOffset; + try + { + // shift to left by preamble offset + Buffer.BlockCopy(transport.m_packet.PacketRaw, preambleOffset, transport.m_packet.PacketRaw, 0, transport.m_packet.PacketByteSize - preambleOffset); + // receive rest of bytes at the end + socket.BeginReceive(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), transport); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); return; + } + return; + } + Packet recvPacket = new Packet(null, 0, shouldReceive); + PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, shouldReceive, transport.m_iocpTcpClient); + try { socket.BeginReceive(recvPacket.PacketRaw, 0, shouldReceive, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), dataTransport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); + return; } - Packet recvPacket = new Packet(null, 0, shouldReceive); - PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, shouldReceive, transport.m_iocpTcpClient); - try { socket.BeginReceive(recvPacket.PacketRaw, 0, shouldReceive, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), dataTransport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); - return; - } - } - else - { - PacketTransporter sizeTransport = new PacketTransporter(PacketType.SIZE, transport.m_iocpTcpClient.m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, transport.m_iocpTcpClient); - try { socket.BeginReceive(sizeTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), sizeTransport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); - transport.m_iocpTcpClient.Disconnect(); - return; + } + else + { + PacketTransporter sizeTransport = new PacketTransporter(PacketType.SIZE, transport.m_iocpTcpClient.m_recvSizePacket, 0, Preamble.SIZE_PACKET_LENGTH, transport.m_iocpTcpClient); + try { socket.BeginReceive(sizeTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onReceived), sizeTransport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.Disconnect(); + return; } - transport.m_iocpTcpClient.OnReceived(transport.m_iocpTcpClient, transport.m_packet); - } - } - } - - /// - /// Send callback function - /// - /// result - private static void onSent(IAsyncResult result) - { - PacketTransporter transport = result.AsyncState as PacketTransporter; - Socket socket = transport.m_iocpTcpClient.m_client.Client; - - int sentSize=0; - try { sentSize = socket.EndSend(result); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.OnReceived(transport.m_iocpTcpClient, transport.m_packet); + } + } + } + + /// + /// Send callback function + /// + /// result + private static void onSent(IAsyncResult result) + { + PacketTransporter transport = result.AsyncState as PacketTransporter; + Socket socket = transport.m_iocpTcpClient.m_client.Client; + + int sentSize=0; + try { sentSize = socket.EndSend(result); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; - } - if (sentSize == 0) - { + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; + } + if (sentSize == 0) + { transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_CONNECTION_CLOSING, transport.m_dataPacket); - return; - } - if (sentSize < transport.m_size) - { - transport.m_offset = transport.m_offset + sentSize; - transport.m_size = transport.m_size - sentSize; - try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_CONNECTION_CLOSING, transport.m_dataPacket); + return; + } + if (sentSize < transport.m_size) + { + transport.m_offset = transport.m_offset + sentSize; + transport.m_size = transport.m_size - sentSize; + try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; - } - } - else - { - if (transport.m_packetType == PacketType.SIZE) - { - transport.m_packet = transport.m_dataPacket; - transport.m_offset = transport.m_dataPacket.PacketOffset; - transport.m_packetType = PacketType.DATA; + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; + } + } + else + { + if (transport.m_packetType == PacketType.SIZE) + { + transport.m_packet = transport.m_dataPacket; + transport.m_offset = transport.m_dataPacket.PacketOffset; + transport.m_packetType = PacketType.DATA; transport.m_size = transport.m_dataPacket.PacketByteSize; - try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } - catch (Exception ex) - { - Console.WriteLine(ex.Message + " >" + ex.StackTrace); + try { socket.BeginSend(transport.m_packet.PacketRaw, transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), transport); } + catch (Exception ex) + { + Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); - return; - } - } - else - { - PacketTransporter delayedTransport = null; - lock (transport.m_iocpTcpClient.m_sendQueueLock) - { - Queue sendQueue = transport.m_iocpTcpClient.m_sendQueue; - if (sendQueue.Count > 0) - { - delayedTransport = sendQueue.Dequeue(); - } - } - if (delayedTransport != null) - { - try { socket.BeginSend(delayedTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), delayedTransport); } - catch (Exception ex) - { + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, transport.m_dataPacket); + return; + } + } + else + { + PacketTransporter delayedTransport = null; + lock (transport.m_iocpTcpClient.m_sendQueueLock) + { + Queue sendQueue = transport.m_iocpTcpClient.m_sendQueue; + if (sendQueue.Count > 0) + { + delayedTransport = sendQueue.Dequeue(); + } + } + if (delayedTransport != null) + { + try { socket.BeginSend(delayedTransport.m_packet.PacketRaw, 0, Preamble.SIZE_PACKET_LENGTH, SocketFlags.None, new AsyncCallback(IocpTcpSocket.onSent), delayedTransport); } + catch (Exception ex) + { Console.WriteLine(ex.Message + " >" + ex.StackTrace); delayedTransport.m_iocpTcpClient.Disconnect(); - delayedTransport.m_iocpTcpClient.OnSent(delayedTransport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, delayedTransport.m_dataPacket); - return; - } - } - else - { - transport.m_iocpTcpClient.m_sendEvent.Unlock(); + delayedTransport.m_iocpTcpClient.OnSent(delayedTransport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR, delayedTransport.m_dataPacket); + return; + } + } + else + { + transport.m_iocpTcpClient.m_sendEvent.Unlock(); } - transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); - } - } - + transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); + } + } + } /// @@ -968,7 +968,7 @@ private void Dispose(bool isDisposing) { this.IsDisposed = true; } - } - - } -} + } + + } +}