//Messages private void messageReceived(KMPCommon.ClientMessageID id, byte[] data) { if (id == KMPCommon.ClientMessageID.SPLIT_MESSAGE) { if (splitMessageReceiveIndex == 0) { //New split message int split_message_length = KMPCommon.intFromBytes(data, 4); splitMessageData = new byte[8 + split_message_length]; data.CopyTo(splitMessageData, 0); splitMessageReceiveIndex = data.Length; } else { //Continued split message data.CopyTo(splitMessageData, splitMessageReceiveIndex); splitMessageReceiveIndex = splitMessageReceiveIndex + data.Length; } //Check if we have filled the byte array, if so, handle the message. if (splitMessageReceiveIndex == splitMessageData.Length) { //Parse the message and feed it into the client queue KMPCommon.ClientMessageID joined_message_id = (KMPCommon.ClientMessageID)KMPCommon.intFromBytes(splitMessageData, 0); int joined_message_length = KMPCommon.intFromBytes(splitMessageData, 4); byte[] joined_message_data = new byte[joined_message_length]; Array.Copy(splitMessageData, 8, joined_message_data, 0, joined_message_length); byte[] joined_message_data_decompressed = KMPCommon.Decompress(joined_message_data); parent.queueClientMessage(this, joined_message_id, joined_message_data_decompressed); splitMessageReceiveIndex = 0; } } else { parent.queueClientMessage(this, id, data); } }
private void handleReceive() { while (receiveHandleIndex < receiveIndex) { //Read header bytes if (currentMessageHeaderIndex < KMPCommon.MSG_HEADER_LENGTH) { //Determine how many header bytes can be read int bytes_to_read = Math.Min(receiveIndex - receiveHandleIndex, KMPCommon.MSG_HEADER_LENGTH - currentMessageHeaderIndex); //Read header bytes Array.Copy(receiveBuffer, receiveHandleIndex, currentMessageHeader, currentMessageHeaderIndex, bytes_to_read); //Advance buffer indices currentMessageHeaderIndex += bytes_to_read; receiveHandleIndex += bytes_to_read; //Handle header if (currentMessageHeaderIndex >= KMPCommon.MSG_HEADER_LENGTH) { int id_int = KMPCommon.intFromBytes(currentMessageHeader, 0); //Make sure the message id section of the header is a valid value if (id_int >= 0 && id_int < Enum.GetValues(typeof(KMPCommon.ClientMessageID)).Length) currentMessageID = (KMPCommon.ClientMessageID)id_int; else currentMessageID = KMPCommon.ClientMessageID.NULL; int data_length = KMPCommon.intFromBytes(currentMessageHeader, 4); if (data_length > KMPCommon.MAX_MESSAGE_SIZE) { throw new InvalidOperationException("Client fed bad data"); } if (data_length > 0) { //Init message data buffer currentMessageData = new byte[data_length]; currentMessageDataIndex = 0; } else { currentMessageData = null; //Handle received message messageReceived(currentMessageID, null); //Prepare for the next header read currentMessageHeaderIndex = 0; } } } if (currentMessageData != null) { //Read data bytes if (currentMessageDataIndex < currentMessageData.Length) { //Determine how many data bytes can be read int bytes_to_read = Math.Min(receiveIndex - receiveHandleIndex, currentMessageData.Length - currentMessageDataIndex); //Read data bytes Array.Copy(receiveBuffer, receiveHandleIndex, currentMessageData, currentMessageDataIndex, bytes_to_read); //Advance buffer indices currentMessageDataIndex += bytes_to_read; receiveHandleIndex += bytes_to_read; //Handle data if (currentMessageDataIndex >= currentMessageData.Length) { //Handle received message byte[] messageData = KMPCommon.Decompress(currentMessageData); if (messageData != null) messageReceived(currentMessageID, messageData); //Consider adding re-request here currentMessageData = null; //Prepare for the next header read currentMessageHeaderIndex = 0; } } } } //Once all receive bytes have been handled, reset buffer indices to use the whole buffer again receiveHandleIndex = 0; receiveIndex = 0; }
private void asyncReceive(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; TcpClient client = state.workClient; int bytesRead = client.GetStream().EndRead(ar); // Read data from the remote device directly into the message buffer. updateReceiveTimestamp(); currentBytesToReceive -= bytesRead; //Decrement how many bytes we have read. if (bytesRead > 0) //This is just a shortcut really { if (!currentMessageHeaderRecieved) { //We are receiving just the header if (currentBytesToReceive == 0) { //We have recieved the full message header, lets process it. currentMessageID = (KMPCommon.ClientMessageID)BitConverter.ToInt32(currentMessage, 0); currentBytesToReceive = BitConverter.ToInt32(currentMessage, 4); if (currentBytesToReceive == 0) { //We received the header of a empty message, process it and reset the buffers. messageReceived(currentMessageID, null); currentMessageID = KMPCommon.ClientMessageID.NULL; currentBytesToReceive = KMPCommon.MSG_HEADER_LENGTH; currentMessage = new byte[currentBytesToReceive]; } else { //We received the header of a non-empty message, Let's give it a buffer and read again. currentMessage = new byte[currentBytesToReceive]; currentMessageHeaderRecieved = true; } } } else { if (currentBytesToReceive == 0) { //We have received all the message data, lets decompress and process it byte[] decompressedData = KMPCommon.Decompress(currentMessage); messageReceived(currentMessageID, decompressedData); currentMessageHeaderRecieved = false; currentMessageID = KMPCommon.ClientMessageID.NULL; currentBytesToReceive = KMPCommon.MSG_HEADER_LENGTH; currentMessage = new byte[currentBytesToReceive]; } } } if (currentBytesToReceive < 0) { throw new System.IO.IOException("You somehow managed to read more bytes then we asked for. Good for you. Open this up on the bugtracker now."); } if (client != null) { client.GetStream().BeginRead(currentMessage, currentMessage.Length - currentBytesToReceive, currentBytesToReceive, new AsyncCallback(asyncReceive), state); } } catch (Exception e) { //Basically, If anything goes wrong at all the stream is broken and there is no way to recover from it. Log.Debug("Exception thrown in ReceiveCallback(), catch 1, Exception: {0}", e.ToString()); } }
//Messages private void messageReceived(KMPCommon.ClientMessageID id, byte[] data) { parent.queueClientMessage(this, id, data); }
private void handleReceive() { while (receiveHandleIndex < receiveIndex) { //Read header bytes if (currentMessageHeaderIndex < KMPCommon.MSG_HEADER_LENGTH) { //Determine how many header bytes can be read int bytes_to_read = Math.Min(receiveIndex - receiveHandleIndex, KMPCommon.MSG_HEADER_LENGTH - currentMessageHeaderIndex); //Read header bytes Array.Copy(receiveBuffer, receiveHandleIndex, currentMessageHeader, currentMessageHeaderIndex, bytes_to_read); //Advance buffer indices currentMessageHeaderIndex += bytes_to_read; receiveHandleIndex += bytes_to_read; //Handle header if (currentMessageHeaderIndex >= KMPCommon.MSG_HEADER_LENGTH) { int id_int = KMPCommon.intFromBytes(currentMessageHeader, 0); //Make sure the message id section of the header is a valid value if (id_int >= 0 && id_int < Enum.GetValues(typeof(KMPCommon.ClientMessageID)).Length) { currentMessageID = (KMPCommon.ClientMessageID)id_int; } else { currentMessageID = KMPCommon.ClientMessageID.NULL; } int data_length = KMPCommon.intFromBytes(currentMessageHeader, 4); if (data_length > 0) { //Init message data buffer currentMessageData = new byte[data_length]; currentMessageDataIndex = 0; } else { currentMessageData = null; //Handle received message messageReceived(currentMessageID, null); //Prepare for the next header read currentMessageHeaderIndex = 0; } } } if (currentMessageData != null) { //Read data bytes if (currentMessageDataIndex < currentMessageData.Length) { //Determine how many data bytes can be read int bytes_to_read = Math.Min(receiveIndex - receiveHandleIndex, currentMessageData.Length - currentMessageDataIndex); //Read data bytes Array.Copy(receiveBuffer, receiveHandleIndex, currentMessageData, currentMessageDataIndex, bytes_to_read); //Advance buffer indices currentMessageDataIndex += bytes_to_read; receiveHandleIndex += bytes_to_read; //Handle data if (currentMessageDataIndex >= currentMessageData.Length) { //Handle received message messageReceived(currentMessageID, currentMessageData); currentMessageData = null; //Prepare for the next header read currentMessageHeaderIndex = 0; } } } } //Once all receive bytes have been handled, reset buffer indices to use the whole buffer again receiveHandleIndex = 0; receiveIndex = 0; }
private void asyncReceive(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; TcpClient client = state.workClient; int bytesRead = client.GetStream().EndRead(ar); // Read data from the remote device directly into the message buffer. updateReceiveTimestamp(); currentBytesToReceive -= bytesRead; //Decrement how many bytes we have read. if (bytesRead > 0) { //This is just a shortcut really if (!currentMessageHeaderRecieved) { //We are receiving just the header if (currentBytesToReceive == 0) { //We have recieved the full message header, lets process it. currentMessageID = (KMPCommon.ClientMessageID)BitConverter.ToInt32(currentMessage, 0); currentBytesToReceive = BitConverter.ToInt32(currentMessage, 4); if (currentBytesToReceive == 0) { //We received the header of a empty message, process it and reset the buffers. messageReceived(currentMessageID, null); currentMessageID = KMPCommon.ClientMessageID.NULL; currentBytesToReceive = KMPCommon.MSG_HEADER_LENGTH; currentMessage = new byte[currentBytesToReceive]; } else { //We received the header of a non-empty message, Let's give it a buffer and read again. currentMessage = new byte[currentBytesToReceive]; currentMessageHeaderRecieved = true; } } } else { if (currentBytesToReceive == 0) { //We have received all the message data, lets decompress and process it byte[] decompressedData = KMPCommon.Decompress(currentMessage); messageReceived(currentMessageID, decompressedData); currentMessageHeaderRecieved = false; currentMessageID = KMPCommon.ClientMessageID.NULL; currentBytesToReceive = KMPCommon.MSG_HEADER_LENGTH; currentMessage = new byte[currentBytesToReceive]; } } } if (currentBytesToReceive < 0) { throw new System.IO.IOException("You somehow managed to read more bytes then we asked for. Good for you. Open this up on the bugtracker now."); } if (client != null) { client.GetStream().BeginRead(currentMessage, currentMessage.Length - currentBytesToReceive, currentBytesToReceive, new AsyncCallback(asyncReceive), state); } } catch (Exception e) { //Basically, If anything goes wrong at all the stream is broken and there is no way to recover from it. Log.Debug("Exception thrown in ReceiveCallback(), catch 1, Exception: {0}", e.ToString()); } }