// Thread for incomming connection private void ConnectingThread(IAsyncResult ar) { Socket sock = null; try { if (Listener == null && Client == null) { return; } if (Listener != null) { sock = Listener.EndAcceptSocket(ar); } sock.SendBufferSize = BUF_SIZE; sock.ReceiveBufferSize = BUF_SIZE; sock.NoDelay = false; sock.Blocking = false; BaseClient baseClient = null; try { string ip = sock.Connected ? sock.RemoteEndPoint.ToString() : "socket disconnected"; if (Listener != null) { Log.Info("TCPManager", "New Connection : " + ip); } if (Client != null) { Log.Info("TCPManager", "New connection to : " + ip); } baseClient = GetNewClient(); baseClient.Socket = sock; baseClient.OnConnect(); baseClient.BeginReceive(); } catch (SocketException) { if (baseClient != null) { Disconnect(baseClient); } } catch (Exception e) { Log.Error("TCPManager", e.ToString()); if (baseClient != null) { Disconnect(baseClient); } } } catch { if (sock != null) // Ne pas laisser le socket ouvert { try { sock.Close(); } catch { } } } finally { if (Listener != null) // Quoi qu'il arrive on continu d'écouter le socket { Listener.BeginAcceptSocket(_asyncAcceptCallback, this); } } }
private static void OnReceiveHandler(IAsyncResult ar) { if (ar == null) { return; } BaseClient baseClient = null; try { baseClient = (BaseClient)ar.AsyncState; int numBytes = baseClient.Socket.EndReceive(ar); if (numBytes > 0 || (numBytes <= 0 && DisconnectOnNullByte == false)) { Log.Tcp(baseClient.GetIp, baseClient.ReceiveBuffer, 0, numBytes); byte[] buffer = baseClient.ReceiveBuffer; int bufferSize = baseClient.ReceiveBufferOffset + numBytes; baseClient.ReceiveBufferOffset = 0; byte[] Packet = new byte[bufferSize]; Buffer.BlockCopy(buffer, 0, Packet, 0, bufferSize); baseClient.OnReceive(Packet); baseClient.BeginReceive(); } else { Log.Debug("BaseClient", "disconnection of client (" + baseClient.GetIp + "), received bytes=" + numBytes); baseClient._srvr.Disconnect(baseClient); } } catch (ObjectDisposedException) { if (baseClient != null) { baseClient._srvr.Disconnect(baseClient); } } catch (SocketException e) { if (baseClient != null) { Log.Info("BaseClient", string.Format("{0} {1}", baseClient.GetIp, e.Message)); baseClient._srvr.Disconnect(baseClient); } } catch (Exception e) { Log.Error("BaseClient", e.ToString()); if (baseClient != null) { baseClient._srvr.Disconnect(baseClient); } } }
protected static void AsyncTcpSendCallback(IAsyncResult ar) { if (ar == null) { Log.Error("BaseClient", "AsyncSendCallback: ar == null"); return; } BaseClient client = (BaseClient)ar.AsyncState; try { Queue <byte[]> q = client.m_tcpQueue; int sent = client.Socket.EndSend(ar); int count = 0; byte[] data = client.m_tcpSendBuffer; if (data == null) { Log.Error("TcpCallBack", "Data == null"); return; } lock (q) { if (q.Count > 0) { count = CombinePackets(data, q, data.Length, client); } if (count <= 0) { client.m_sendingTcp = false; return; } } int start = Environment.TickCount; if (client.m_crypts.Count <= 0) { Log.Tcp("SendTCPAs", data, 0, count); } else { Log.Tcp("CryptedAs", data, 0, count); } client.Socket.BeginSend(data, 0, count, SocketFlags.None, m_asyncTcpCallback, client); int took = Environment.TickCount - start; } catch (ObjectDisposedException) { client._srvr.Disconnect(client); } catch (SocketException) { client._srvr.Disconnect(client); } catch (Exception) { client._srvr.Disconnect(client); } }
public void HandlePacket(BaseClient client, PacketIn packet) { //#if DEBUG Log.Debug("HandlePacket", $"Packet : {packet.Opcode} ({packet.Opcode.ToString("X8")})"); Log.Dump("HandlePacket", packet.ToArray(), 0, packet.ToArray().Length); //#endif if (client == null) { Log.Error("TCPManager", "Client == null"); return; } PacketFunction packetHandler = null; if (packet.Opcode < (ulong)m_packetHandlers.Length) { packetHandler = m_packetHandlers[packet.Opcode]; } else if (!Errors.Contains(packet.Opcode)) { Errors.Add(packet.Opcode); Log.Error("TCPManager", $"Can not handle :{packet.Opcode} ({packet.Opcode.ToString("X8")})"); } if (packetHandler != null) { /* * * The reflection code below seems to have been used to verify the client was in the correct state before the packet was handled. * However, it didn't actually work; eliminating the reflection and using an array implementation broke the emu and testing confirmed * the original check was broken, so I've eliminated it for now. * * * if (stateRequirement[packet.Opcode] > client.State) * { * Log.Error("TCPManager", $"Can not handle packet ({packet.Opcode.ToString("X8")}), Invalid client state {client.State} (expected {stateRequirement[packet.Opcode]}) ({client.GetIp()})"); * PacketHandlerAttribute[] packethandlerattribs = (PacketHandlerAttribute[])packetHandler.GetType().GetCustomAttributes(typeof(PacketHandlerAttribute), true); * if (packethandlerattribs.Length > 0) * { * Log.Error("TCPManager", $"Old code provided state {packethandlerattribs[0].State}"); * if (packethandlerattribs[0].State > client.State) * return; * } * else * { * Log.Error("TCPManager", "Old code was stateless"); * } * } */ try { packetHandler.Invoke(client, packet); } catch (Exception e) { Log.Error("TCPManager", $"Packet handler error :{packet.Opcode} {e}"); } } else if (!Errors.Contains(packet.Opcode)) { Errors.Add(packet.Opcode); Log.Error("TCPManager", $"Can not Handle opcode :{packet.Opcode} ({packet.Opcode.ToString("X8")})"); } }