void ReceiveCallback(IAsyncResult ar) { bool recsuccess = false; RecState state = null; try { int bytesgotten = S.EndReceive(ar); state = (RecState)ar.AsyncState; state.BytesSoFar += bytesgotten; recsuccess = true; #if DEBUG Console.WriteLine("Receive Callback. Packet: {0} First packet: {1}, Bytes so far: {2}", state.PacketCount, state.IsPacketLength, state.BytesSoFar); #endif } catch (SocketException) { OnError(ConnectionClosed); S.Close(); } catch (Exception) { //disconnect request, catiching mainly accessing disposed socket OnDisconnected(Disconnected); //OnError("EXCEPTION: " + e.Message); } if (recsuccess) { ProcessIncomingData(state); } }
void ProcessIncomingData(RecState state) { if (state.IsPacketLength) { // First 4 bytes of a new packet. state.PacketLength = BitConverter.ToInt32(state.Data, 0); state.IsPacketLength = false; state.BytesSoFar = 0; state.Data = new byte[state.PacketLength]; S.BeginReceive(state.Data, 0, state.PacketLength, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } else { // Do something with data... if (state.BytesSoFar < state.PacketLength) { // Missing data. S.BeginReceive(state.Data, state.BytesSoFar, state.PacketLength - state.BytesSoFar, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } else { // Process data. #if DEBUG Console.WriteLine("Complete packet."); #endif RCONPacket RetPack = new RCONPacket(); if (state.Data.Length != 0) { RetPack.ParseFromBytes(state.Data, this); ProcessResponse(RetPack); // Wait for new packet. if (S.Connected) { StartGetNewPacket(); } } else { //Console.WriteLine("KICKED TIMEOUT DATA:" + UTF8Encoding.UTF8.GetString(state.Data)); OnError(ConnectionClosed); S.Close(); } return; } } }
void StartGetNewPacket() { RecState state = new RecState(); state.IsPacketLength = true; state.Data = new byte[4]; state.PacketCount = PacketCount; PacketCount++; #if DEBUG TempPackets.Add(state); #endif try { S.BeginReceive(state.Data, 0, 4, SocketFlags.None, new AsyncCallback(ReceiveCallback), state); } catch (Exception) { } }