/// <summary> /// Send given packet to the client /// </summary> /// <param name="packet">the packet to send</param> public void Send(Packet packet) { if (!IsConnectionAlive) { 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); //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); } } } }
/// <summary> /// Receive callback function /// </summary> /// <param name="result">result</param> 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); // 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; } 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 { 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; } transport.m_iocpTcpClient.OnReceived(transport.m_iocpTcpClient, transport.m_packet); } } }