/// <summary> /// Start to receive packet from the server /// </summary> private void startReceive() { m_serverType = m_server.GetServerType(); switch (m_server.GetServerType()) { case ServerType.RADAR: m_headerLength = Marshal.SizeOf(typeof(BLOCK_HEADER_T)); m_recvPacket = new Packet(null, 7); break; case ServerType.EOIR: case ServerType.EOIRByPassServer: m_headerLength = Marshal.SizeOf(typeof(EOIR_Header)); m_recvPacket = new Packet(null, 12); break; } if (m_headerLength > 0) { // 수정 필요 PacketTransporter transport = new PacketTransporter(PacketType.HEADER, m_recvPacket, 0, m_headerLength, this); try { m_client.Client.BeginReceive(m_recvPacket.GetPacket(), 0, m_headerLength, SocketFlags.None, new AsyncCallback(onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); Disconnect(); return; } } }
/// <summary> /// Receive callback function /// </summary> /// <param name="result">result</param> private static void onReceived(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; NetworkStream socket = transport.m_iocpTcpClient.m_clientStream; int readSize = 0; try { readSize = socket.EndRead(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.BeginRead(transport.m_packet.GetPacket(), transport.m_offset, transport.m_size, 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.GetPacket(), 0); Packet recvPacket = new Packet(null, shouldReceive); PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, shouldReceive, transport.m_iocpTcpClient); try{ socket.BeginRead(recvPacket.GetPacket(), 0, shouldReceive, 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, 4, transport.m_iocpTcpClient); try { socket.BeginRead(sizeTransport.m_packet.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onReceived), sizeTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); return; } transport.m_callBackObj.OnReceived(transport.m_iocpTcpClient, transport.m_packet); } } }
/// <summary> /// Send given packet to the client /// </summary> /// <param name="packet">the packet to send</param> public void Send(Packet packet) { if (!IsConnectionAlive()) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_NOT_CONNECTED); }); t.Start(); } return; } if (packet.GetPacketByteSize() <= 0) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_INVALID_PACKET); }); t.Start(); } return; } lock (m_sendLock) { int packetSize = packet.GetPacketByteSize(); PacketTransporter transport = new PacketTransporter(PacketType.DATA, m_sendPacket, 0, packetSize, this, -1, packet); //m_sendPacket.SetPacket(BitConverter.GetBytes(packet.GetPacketByteSize()), 0); m_sendPacket.SetPacket(packet.GetPacket(), 0); while (true) { if (m_sendEvent.TryLock()) { try { m_client.Client.BeginSend(m_sendPacket.GetPacket(), 0, packetSize, SocketFlags.None, new AsyncCallback(onSent), transport); break; } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); Disconnect(); return; } } } //else //{ // lock (m_sendQueueLock) // { // m_sendQueue.Enqueue(transport); // } //} } }
/// <summary> /// Send given packet to the server /// </summary> /// <param name="packet">packet to send</param> public void Send(Packet packet) { if (!IsConnectionAlive()) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_NOT_CONNECTED); }); t.Start(); } return; } if (packet.GetPacketByteSize() <= 0) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_INVALID_PACKET); }); t.Start(); } return; } lock (m_sendLock) { Packet sendSizePacket = new Packet(null, 4, false); PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, 4, this, packet); sendSizePacket.SetPacket(BitConverter.GetBytes(packet.GetPacketByteSize()), 4); if (m_sendEvent.TryLock()) { try { m_clientStream.BeginWrite(sendSizePacket.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); if (m_callBackObj != null) { m_callBackObj.OnSent(this, SendStatus.FAIL_SOCKET_ERROR); } Disconnect(); return; } } else { lock (m_sendQueueLock) { m_sendQueue.Enqueue(transport); } } } }
/// <summary> /// Start to receive packet from the server /// </summary> 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; } }
/// <summary> /// Start to receive packet from the server /// </summary> private void startReceive() { PacketTransporter transport = new PacketTransporter(PacketType.SIZE, m_recvSizePacket, 0, 4, this); try { m_clientStream.BeginRead(m_recvSizePacket.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); Disconnect(); return; } }
private void startReceive() { // TCP/IP 패킷의 헤더부터 먼저 수신 PacketTransporter transport = new PacketTransporter(PacketType.HEADER, m_headerPacket, 0, m_headerLength, this); try { m_client.Client.BeginReceive(m_headerPacket.GetPacket(), 0, m_headerLength, SocketFlags.None, new AsyncCallback(onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); Disconnect(); return; } }
/// <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); } } } }
private void onReceived(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; Socket socket = transport.m_TcpClient.m_client.Client; int headerLength = transport.m_TcpClient.m_headerLength; //소켓 통신에서 읽은 데이터 사이즈 int readSize = 0; try { readSize = socket.EndReceive(result); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } //읽은 데이터 사이즈가 0일 경우 통신 절단 if (readSize == 0) { transport.m_TcpClient.Disconnect(); return; } // True : 읽어야 할 데이터보다 적게 들어온 경우 더 받기 위해 Receive , False : 파싱 할 데이터가 모드 들어온 경우 HEADER 또는 DATA 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.GetPacket(), transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } else { //True : 해더, False : 데이터 if (transport.m_packetType == PacketType.HEADER) { //해더 바이트 byte[] header = transport.m_packet.GetPacket(); //해더안의 데이터 길이를 알기 위한 변수 int DataLength = 0; //체크 썸을 확인 하는 변수 bool isCheckSum = false; //블록 타입 int iBlockType = 0; //SetServerType을 이용한 서버 타입 Connect 하기 전에 설정된 타입값 switch (m_serverType) { //페이로드 길이, 블록 타입, 체크 썸 결과를 반환한다. case ServerType.RADAR: isCheckSum = Radar_Packet_Receive(header, ref DataLength, ref iBlockType); break; case ServerType.EOIR: case ServerType.EOIRByPassServer: isCheckSum = EoIr_Packet_Receive(header, ref DataLength, ref iBlockType); break; } //True : 완전한 헤더 데이터, False : 잘못된 헤더 데이터 if (isCheckSum && DataLength > 0) { //페이로드 수신 대기 Packet recvPacket = new Packet(null, DataLength); PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, DataLength, transport.m_TcpClient); dataTransport.HeaderPacket = transport.m_packet; dataTransport.m_DataType = iBlockType; try { socket.BeginReceive(recvPacket.GetPacket(), 0, DataLength, SocketFlags.None, new AsyncCallback(onReceived), dataTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } //수신된 헤더 데이터 콜백 리시브 //transport.m_callBackObj.OnReceived(transport.m_TcpClient, new Packet(header, header.Length), iBlockType); } else { //해더 데이터만 존재하는 데이터 블록 리시브 콜백 if (isCheckSum) { Packet packet = new Packet(header, header.Length); packet.SetDateTime(); transport.m_callBackObj.OnReceived(transport.m_TcpClient, packet, iBlockType); } else { } //헤더 데이터 재수신 대기 PacketTransporter headerTransport = new PacketTransporter(PacketType.HEADER, transport.m_TcpClient.m_headerPacket, 0, headerLength, transport.m_TcpClient); try { socket.BeginReceive(transport.m_TcpClient.m_headerPacket.GetPacket(), 0, headerLength, SocketFlags.None, new AsyncCallback(onReceived), headerTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } } else { //페이로드 리시브 콜백 transport.m_dataPacket = transport.m_packet; //리시브 받은 현재 시간을 저장 transport.m_dataPacket.SetDateTime(); transport.m_callBackObj.OnReceived(transport.m_TcpClient, transport.m_dataPacket, transport.m_DataType); //페이로드가 정상 수신되어 해더 데이터 재수신 대기 PacketTransporter headerTransport = new PacketTransporter(PacketType.HEADER, transport.m_TcpClient.m_headerPacket, 0, headerLength, transport.m_TcpClient); try { socket.BeginReceive(headerTransport.m_packet.GetPacket(), 0, headerLength, SocketFlags.None, new AsyncCallback(onReceived), headerTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } } }
/// <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); } } }
/// <summary> /// Send given packet to the server /// </summary> /// <param name="packet">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()), 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) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); OnSent(this, SendStatus.FAIL_SOCKET_ERROR, packet); Disconnect(); return; } } else { lock (m_sendQueueLock) { m_sendQueue.Enqueue(transport); } } } }
/// <summary> /// Send callback function /// </summary> /// <param name="result">result</param> private static void onSent(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; NetworkStream socket = transport.m_iocpTcpClient.m_clientStream; int sentSize = 0; try { sentSize = socket.EndWrite(result); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } if (sentSize == 0) { transport.m_iocpTcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_CONNECTION_CLOSING); return; } if (sentSize < transport.m_size) { transport.m_offset = transport.m_offset + sentSize; transport.m_size = transport.m_size - sentSize; try { socket.BeginWrite(transport.m_packet.GetPacket(), transport.m_offset, transport.m_size, new AsyncCallback(IocpTcpClient.onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { if (transport.m_packetType == PacketType.SIZE) { transport.m_packet = transport.m_dataPacket; transport.m_offset = 0; transport.m_packetType = PacketType.DATA; transport.m_size = transport.m_dataPacket.GetPacketByteSize(); try { socket.BeginWrite(transport.m_packet.GetPacket(), 0, transport.m_size, new AsyncCallback(IocpTcpClient.onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { PacketTransporter delayedTransport = null; lock (transport.m_iocpTcpClient.m_sendQueueLock) { Queue <PacketTransporter> sendQueue = transport.m_iocpTcpClient.m_sendQueue; if (sendQueue.Count > 0) { delayedTransport = sendQueue.Dequeue(); } } if (delayedTransport != null) { try { socket.BeginWrite(delayedTransport.m_packet.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onSent), delayedTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS); delayedTransport.m_iocpTcpClient.Disconnect(); delayedTransport.m_callBackObj.OnSent(delayedTransport.m_iocpTcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { transport.m_iocpTcpClient.m_sendEvent.Unlock(); } transport.m_callBackObj.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS); } } }
/// <summary> /// Receive callback function /// </summary> /// <param name="result">result</param> private static void onReceived(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; NetworkStream socket = transport.m_iocpTcpClient.m_clientStream; int readSize=0; try { readSize = socket.EndRead(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.BeginRead(transport.m_packet.GetPacket(), transport.m_offset, transport.m_size, 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.GetPacket(), 0); Packet recvPacket = new Packet(null, shouldReceive); PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, shouldReceive, transport.m_iocpTcpClient); try{socket.BeginRead(recvPacket.GetPacket(), 0, shouldReceive, 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, 4, transport.m_iocpTcpClient); try { socket.BeginRead(sizeTransport.m_packet.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onReceived), sizeTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_iocpTcpClient.Disconnect(); return; } transport.m_callBackObj.OnReceived(transport.m_iocpTcpClient, transport.m_packet); } } }
/// <summary> /// Start to receive packet from the server /// </summary> private void startReceive() { PacketTransporter transport = new PacketTransporter(PacketType.SIZE,m_recvSizePacket, 0, 4, this); try { m_clientStream.BeginRead(m_recvSizePacket.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); Disconnect(); return; } }
/// <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); } } }
public void Send(Packet packet) { if (!IsConnectionAlive()) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_NOT_CONNECTED); }); t.Start(); } return; } if (packet.GetPacketByteSize() <= 0) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_INVALID_PACKET); }); t.Start(); } return; } lock (m_sendLock) { // 전송 예외 처리를 위한 설정 int headSize = packet.GetPacketByteSize(); Packet sendSizePacket = new Packet(null, headSize, false); PacketTransporter transport = new PacketTransporter(PacketType.DATA, sendSizePacket, 0, headSize, this, -1, packet); // 전송 패킷 설정 sendSizePacket.SetPacket(packet.GetPacket(), 0); //while (true) //{ if (m_sendEvent.TryLock()) { try { m_client.Client.BeginSend(sendSizePacket.GetPacket(), 0, headSize, SocketFlags.None, new AsyncCallback(onSent), transport); //break; } catch (Exception ex) { // 예외 발생시 콜백 수신되는 transport로 재전송 처리 Console.WriteLine(ex.Message + " >" + ex.StackTrace); if (m_callBackObj != null) { m_callBackObj.OnSent(this, SendStatus.FAIL_SOCKET_ERROR); } Disconnect(); return; } } //} else { lock (m_sendQueueLock) { m_sendQueue.Enqueue(transport); } } } }
/// <summary> /// Send callback function /// </summary> /// <param name="result">result</param> private void onSent(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; Socket socket = transport.m_TcpClient.m_client.Client; int sentSize = 0; try { sentSize = socket.EndSend(result); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } if (sentSize == 0) { transport.m_TcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.FAIL_CONNECTION_CLOSING); 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.GetPacket(), transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { #region Not Used (차후 수정 필요) if (transport.m_packetType == PacketType.HEADER) { transport.m_packet = transport.m_dataPacket; transport.m_offset = 0; transport.m_packetType = PacketType.DATA; transport.m_size = transport.m_dataPacket.GetPacketByteSize(); try { socket.BeginSend(transport.m_packet.GetPacket(), 0, transport.m_size, SocketFlags.None, new AsyncCallback(onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { PacketTransporter delayedTransport = null; lock (transport.m_TcpClient.m_sendQueueLock) { Queue <PacketTransporter> sendQueue = transport.m_TcpClient.m_sendQueue; if (sendQueue.Count > 0) { delayedTransport = sendQueue.Dequeue(); } } if (delayedTransport != null) { try { socket.BeginSend(delayedTransport.m_packet.GetPacket(), 0, delayedTransport.m_size, SocketFlags.None, new AsyncCallback(onSent), delayedTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.FAIL_SOCKET_ERROR); return; } } else { transport.m_TcpClient.m_sendEvent.Unlock(); } transport.m_callBackObj.OnSent(transport.m_TcpClient, SendStatus.SUCCESS); } #endregion } }
/// <summary> /// Receive callback function /// </summary> /// <param name="result">result</param> private void onReceived(IAsyncResult result) { PacketTransporter transport = result.AsyncState as PacketTransporter; Socket socket = transport.m_TcpClient.m_client.Client; int headerLength = transport.m_TcpClient.m_headerLength; int readSize = 0; try { readSize = socket.EndReceive(result); } catch (Exception ex) { Console.WriteLine(ex.Message); transport.m_TcpClient.Disconnect(); return; } // 소켓이 끊겼을 때 클라이언트 disconnect if (readSize == 0) { transport.m_TcpClient.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.GetPacket(), transport.m_offset, transport.m_size, SocketFlags.None, new AsyncCallback(onReceived), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } else { // 수신 받은 패킷이 헤더일 경우 다시 데이터 수신 준비 if (transport.m_packetType == PacketType.HEADER) { //해더 바이트 byte[] header = transport.m_packet.GetPacket(); //해더 안의 데이터 길이를 알기 위한 변수 int DataLength = 0; //체크 썸을 확인 하는 변수 bool isCheckSum = false; //블록 타입 int iBlockType = 0; switch (m_serverType) { case ServerType.RADAR: //Little Endian isCheckSum = Radar_Packet_Receive(header, ref DataLength, ref iBlockType); break; case ServerType.EOIR: case ServerType.EOIRByPassServer: isCheckSum = EoIr_Packet_Receive(header, ref DataLength, ref iBlockType); break; } if (isCheckSum && DataLength > 0) { //transport.m_callBackObj.OnReceived(transport.m_TcpClient, transport.m_packetType, new Packet(header, header.Length)); Packet recvPacket = new Packet(null, DataLength); PacketTransporter dataTransport = new PacketTransporter(PacketType.DATA, recvPacket, 0, DataLength, transport.m_TcpClient); dataTransport.HeaderPacket = transport.m_packet; dataTransport.m_DataType = iBlockType; try { socket.BeginReceive(recvPacket.GetPacket(), 0, DataLength, SocketFlags.None, new AsyncCallback(onReceived), dataTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } else { // 헤더 데이터만 존재하는 데이터 블록 리시브 콜백 if (isCheckSum) { Packet packet = new Packet(header, header.Length); packet.SetDateTime(); transport.m_callBackObj.OnReceived(transport.m_TcpClient, packet, iBlockType); } else { } //Packet recvPacket = new Packet(header, headerLength); //헤더 데이터 재수신 대기 PacketTransporter headerTransport = new PacketTransporter(PacketType.HEADER, transport.m_TcpClient.m_recvPacket, 0, headerLength, transport.m_TcpClient); try { socket.BeginReceive(transport.m_TcpClient.m_recvPacket.GetPacket(), 0, headerLength, SocketFlags.None, new AsyncCallback(onReceived), headerTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } } else { //if (m_serverType == ServerType.EOIR) //{ // transport.m_dataPacket = transport.m_packet; // transport.HeaderPacket.SetDateTime(); // transport.m_dataPacket.SetDateTime(); // transport.m_callBackObj.OnReceived(transport.m_TcpClient, transport.HeaderPacket, transport.m_dataPacket); //} //else //{ //페이로드 리시브 콜백 transport.m_dataPacket = transport.m_packet; //리시브 받은 현재 시간을 저장 transport.m_dataPacket.SetDateTime(); transport.m_callBackObj.OnReceived(transport.m_TcpClient, transport.m_dataPacket, transport.m_DataType); //} PacketTransporter sizeTransport = new PacketTransporter(PacketType.HEADER, transport.m_TcpClient.m_recvPacket, 0, headerLength, transport.m_TcpClient); try { socket.BeginReceive(sizeTransport.m_packet.GetPacket(), 0, headerLength, SocketFlags.None, new AsyncCallback(onReceived), sizeTransport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); transport.m_TcpClient.Disconnect(); return; } } } }
/// <summary> /// Send callback function /// </summary> /// <param name="result">result</param> 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.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.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_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); 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 <PacketTransporter> 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); 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(); } transport.m_iocpTcpClient.OnSent(transport.m_iocpTcpClient, SendStatus.SUCCESS, transport.m_dataPacket); } } }
/// <summary> /// Send given packet to the server /// </summary> /// <param name="packet">packet to send</param> public void Send(Packet packet) { if (!IsConnectionAlive()) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_NOT_CONNECTED); }); t.Start(); } return; } if (packet.GetPacketByteSize() <= 0) { if (m_callBackObj != null) { Thread t = new Thread(delegate() { m_callBackObj.OnSent(this, SendStatus.FAIL_INVALID_PACKET); }); t.Start(); } return; } lock (m_sendLock) { Packet sendSizePacket = new Packet(null, 4, false); PacketTransporter transport = new PacketTransporter(PacketType.SIZE, sendSizePacket, 0, 4, this, packet); sendSizePacket.SetPacket(BitConverter.GetBytes(packet.GetPacketByteSize()), 4); if (m_sendEvent.TryLock()) { try { m_clientStream.BeginWrite(sendSizePacket.GetPacket(), 0, 4, new AsyncCallback(IocpTcpClient.onSent), transport); } catch (Exception ex) { Console.WriteLine(ex.Message + " >" + ex.StackTrace); if (m_callBackObj != null) m_callBackObj.OnSent(this, SendStatus.FAIL_SOCKET_ERROR); Disconnect(); return; } } else { lock (m_sendQueueLock) { m_sendQueue.Enqueue(transport); } } } }