public static MainPacket Create(PacketHeader header, byte[] bytes, int index) { MainPacket tmpPacket = new MainPacket(); tmpPacket.header = header; int offset = 0; tmpPacket.blocksize = BitConverter.ToUInt64(bytes, index + offset); offset += sizeof(UInt64); tmpPacket.recoverablefilecount = BitConverter.ToUInt32(bytes, index + offset); offset += sizeof(UInt32); tmpPacket.totalfilecount = ((uint)header.length - ((uint)header.GetSize() + sizeof(UInt64) + sizeof(UInt32))) / (16 * sizeof(byte)); for (int i = 0; i < tmpPacket.totalfilecount; i++) { byte[] fileid = new byte[16]; Buffer.BlockCopy(bytes, index + offset, fileid, 0, fileid.Length * sizeof(byte)); offset += fileid.Length * sizeof(byte); tmpPacket.fileids.Add(fileid); } System.Threading.Tasks.Task.Factory.StartNew((b) => { //FastCRC32.FastCRC32 crc32 = new FastCRC32.FastCRC32((ulong)b); FastCRC32.FastCRC32 crc32 = FastCRC32.FastCRC32.GetCRC32Instance((ulong)b); }, tmpPacket.blocksize); return tmpPacket; }
public string name; // Name of the file, padded with 1 to 3 zero bytes to reach #endregion Fields #region Methods public static FileDescriptionPacket Create(PacketHeader header, byte[] bytes, int index) { FileDescriptionPacket tmpPacket = new FileDescriptionPacket(); tmpPacket.header = header; int offset = 0; Buffer.BlockCopy(bytes, index + offset, tmpPacket.fileid, 0, tmpPacket.fileid.Length * sizeof(byte)); offset += tmpPacket.fileid.Length * sizeof(byte); Buffer.BlockCopy(bytes, index + offset, tmpPacket.hashfull, 0, tmpPacket.hashfull.Length * sizeof(byte)); offset += tmpPacket.hashfull.Length * sizeof(byte); Buffer.BlockCopy(bytes, index + offset, tmpPacket.hash16k, 0, tmpPacket.hash16k.Length * sizeof(byte)); offset += tmpPacket.hash16k.Length * sizeof(byte); tmpPacket.length = BitConverter.ToUInt64(bytes, index + offset); offset += sizeof(UInt64); // Name is specific to read since it's dependant of packet.length int name_offset = index + offset; int name_size = (int)header.length - header.GetSize() - tmpPacket.fileid.Length * sizeof(byte) - tmpPacket.hashfull.Length * sizeof(byte) - tmpPacket.hash16k.Length * sizeof(byte) - sizeof(UInt64); byte[] name = new byte[name_size]; Buffer.BlockCopy(bytes, name_offset, name, 0, name_size); tmpPacket.name = ToolKit.ByteArrayToString(name).TrimEnd('\0'); return tmpPacket; }
public PackerHandlerAttribute(PacketHeader methodId, string name, int size, PacketDirection direction) { this.MethodId = (ushort)methodId; this.Name = name; this.Size = size; this.Direction = direction; }
public byte[] fileid = new byte[16]; // MD5hash of file_hash_16k, file_length, file_name #endregion Fields #region Methods public static FileVerificationPacket Create(PacketHeader header, byte[] bytes, int index) { FileVerificationPacket tmpPacket = new FileVerificationPacket(); tmpPacket.header = header; int offset = 0; Buffer.BlockCopy(bytes, index + offset, tmpPacket.fileid, 0, tmpPacket.fileid.Length * sizeof(byte)); offset += tmpPacket.fileid.Length * sizeof(byte); int nbEntries = ((int)header.length - header.GetSize() - (16 * sizeof(byte))) / FileVerificationEntry.GetSize(); tmpPacket.entries = new List<FileVerificationEntry>(); tmpPacket.blockcount = (ulong)((header.length - (ulong)tmpPacket.GetSize()) / (ulong)FileVerificationEntry.GetSize()); for (int i = 0; i < nbEntries; i++) { FileVerificationEntry entry = new FileVerificationEntry(); Buffer.BlockCopy(bytes, index + offset, entry.hash, 0, entry.hash.Length * sizeof(byte)); offset += entry.hash.Length * sizeof(byte); entry.crc = BitConverter.ToUInt32(bytes, index + offset); offset += sizeof(UInt32); tmpPacket.entries.Add(entry); } return tmpPacket; }
public virtual Packet CreateUpdatePacket(PacketHeader Header) { List<object> vals = new List<object>(new object[3]); vals[0] = (Position!=LastPosition)?Position:null; vals[1]=(Rotation!=LastRotation)?Rotation:null; vals[2]=(Movement!=LastMovement)?Movement:null; return new Packet(Header) { _data = vals }; }
/// <summary> /// Initialise a new PriorityQueueItem /// </summary> /// <param name="priority"></param> /// <param name="connection"></param> /// <param name="packetHeader"></param> /// <param name="dataStream"></param> /// <param name="sendReceiveOptions"></param> public PriorityQueueItem(QueueItemPriority priority, Connection connection, PacketHeader packetHeader, MemoryStream dataStream, SendReceiveOptions sendReceiveOptions) { if (connection == null) throw new ArgumentNullException("connection", "Provided Connection parameter cannot be null."); if (packetHeader == null) throw new ArgumentNullException("packetHeader", "Provided PacketHeader parameter cannot be null."); if (dataStream == null) throw new ArgumentNullException("dataStream", "Provided MemoryStream parameter cannot be null."); if (sendReceiveOptions == null) throw new ArgumentNullException("sendReceiveOptions", "Provided sendReceiveOptions cannot be null."); this.Priority = priority; this.Connection = connection; this.PacketHeader = packetHeader; this.DataStream = dataStream; this.SendReceiveOptions = sendReceiveOptions; }
public bool Deserialize(byte[] data, ref PacketHeader serialized) { // 디시리얼라이즈할 데이터를 설정합니다. bool ret = SetDeserializedData(data); if (ret == false) { return false; } // 데이터의 요소별로 디시리얼라이즈합니다. int packetId = 0; ret &= Deserialize(ref packetId); serialized.packetId = (PacketId)packetId; return ret; }
public bool Serialize(PacketHeader data) { // 기존 데이터를 클리어합니다. Clear(); // 각 요소를 차례로 시리얼라이즈합니다. bool ret = true; ret &= Serialize((int)data.packetId); if (ret == false) { return false; } return true; }
public bool Deserialize(ref PacketHeader serialized) { // 디시리얼라이즈할 데이터를 설정합니다. bool ret = (GetDataSize() > 0)? true : false; if (ret == false) { return false; } // 데이터의 요소마다 디시리얼라이즈합니다. int packetId = 0; ret &= Deserialize(ref packetId); serialized.packetId = (PacketId)packetId; return ret; }
public static CreatorPacket Create(PacketHeader header, byte[] bytes, int index) { CreatorPacket tmpPacket = new CreatorPacket(); tmpPacket.header = header; int offset = 0; // Name is specific to read since it's dependant of packet.length int name_offset = index + offset; int name_size = (int)header.length - header.GetSize(); byte[] name = new byte[name_size]; Buffer.BlockCopy(bytes, name_offset, name, 0, name_size); tmpPacket.client = ToolKit.ByteArrayToString(name); return tmpPacket; }
public static RecoveryPacket Create(PacketHeader header, byte[] bytes, int index, string filename, int file_offset) { RecoveryPacket tmpPacket = new RecoveryPacket(); tmpPacket.header = header; int offset = 0; tmpPacket.exponent = BitConverter.ToUInt32(bytes, index + offset); offset += sizeof(UInt32); tmpPacket.offset = index + offset + file_offset; tmpPacket.length = (int)header.length - header.GetSize() - sizeof(UInt32); tmpPacket.filename = filename; tmpPacket.diskfile = new DiskFile(); tmpPacket.diskfile.Open(filename); tmpPacket.datablock = new DataBlock(); // Set the data block to immediatly follow the header on disk tmpPacket.datablock.SetLocation(tmpPacket.diskfile, (ulong)tmpPacket.offset); tmpPacket.datablock.SetLength((ulong)tmpPacket.length); return tmpPacket; }
public static List<byte> Drain(List<byte> buffer, ConcurrentQueue<Operation> readQueue, ConcurrentQueue<Operation> processQueue) { lock (_sync) { //now grab the first item from the readQueue Operation op; if (!readQueue.TryDequeue(out op)) //no idea what to do with this error, need a generic error handler for the whole instance? throw new Exception("Bytes were received from the buffer but no operations were available in the ReadQueue"); var responseLength = 0; try { //in memcached ordering is preserverd so the first response in the buffer //should be the first item in the readQueue. I have 0 confidence this will work if (buffer[0] != (byte)Magic.Response) throw new Exception("Magic byte is not the first byte in the response"); //get the working set and send that back to the processor responseLength = new PacketHeader(buffer).PacketLength; op.Response = buffer.Take(responseLength).ToArray(); //add the response back to the ProcessQueue to be handled by the Processor thread //processQueue.Enqueue(op); op.Process(op.Response, op.State); } catch (Exception ex) { op.Error(ex, op.State); } //create the new buffer and call drain again return new List<byte>(buffer.Skip(responseLength)); } }
public void PointerUP(PacketHeader header, Connection connection, int[] Points) { MouseEvents.DoMouseUp((uint)Points[1], (uint)Points[2]); }
/// <summary> /// Attempts to use the data provided in packetBuilder to recreate something useful. If we don't have enough data /// yet that value is set in packetBuilder. /// </summary> /// <param name="packetBuilder">The <see cref="PacketBuilder"/> containing incoming cached data</param> protected void IncomingPacketHandleHandOff(PacketBuilder packetBuilder) { int loopCounter = 0; try { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... checking for completed packet with " + packetBuilder.TotalBytesCached.ToString() + " bytes read."); if (packetBuilder.TotalPartialPacketCount == 0) throw new Exception("Executing IncomingPacketHandleHandOff when no packets exist in packetbuilder."); //Loop until we are finished with this packetBuilder while (true) { //If we have ended up with a null packet at the front, probably due to some form of concatenation we can pull it off here //It is possible we have concatenation of several null packets along with real data so we loop until the firstByte is greater than 0 if (ConnectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled && packetBuilder.FirstByte() == 0) { #region Ignore Null Packet if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... null packet removed in IncomingPacketHandleHandOff() from " + ConnectionInfo + ", loop index - " + loopCounter.ToString()); packetBuilder.ClearNTopBytes(1); //Reset the expected bytes to 0 so that the next check starts from scratch packetBuilder.TotalBytesExpected = 0; //If we have run out of data completely then we can return immediately if (packetBuilder.TotalBytesCached == 0) return; #endregion } else { int packetHeaderSize = 0; PacketHeader topPacketHeader; #region Set topPacketHeader if (ConnectionInfo.ApplicationLayerProtocol == ApplicationLayerProtocolStatus.Enabled) { //First determine the expected size of a header packet packetHeaderSize = packetBuilder.FirstByte() + 1; //Do we have enough data to build a header? if (packetBuilder.TotalBytesCached < packetHeaderSize) { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... require " + packetHeaderSize + " bytes for packet header, only " + packetBuilder.TotalBytesCached + " bytes cached."); //Set the expected number of bytes and then return packetBuilder.TotalBytesExpected = packetHeaderSize; return; } if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... deserializing header using " + packetHeaderSize + " bytes, " + packetBuilder.TotalBytesCached + " bytes cached."); //We have enough for a header using (MemoryStream headerStream = packetBuilder.ReadDataSection(1, packetHeaderSize - 1)) topPacketHeader = new PacketHeader(headerStream, NetworkComms.InternalFixedSendReceiveOptions); } else topPacketHeader = new PacketHeader(Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged), packetBuilder.TotalBytesCached); #endregion //Idiot test if (topPacketHeader.PacketType == null) throw new SerialisationException("packetType value in packetHeader should never be null"); //We can now use the header to establish if we have enough payload data //First case is when we have not yet received enough data if (packetBuilder.TotalBytesCached < packetHeaderSize + topPacketHeader.TotalPayloadSize) { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... more data required for complete packet payload. Expecting " + (packetHeaderSize + topPacketHeader.TotalPayloadSize).ToString() + " total packet bytes."); //Set the expected number of bytes and then return packetBuilder.TotalBytesExpected = packetHeaderSize + topPacketHeader.TotalPayloadSize; return; } //Second case is we have enough data else if (packetBuilder.TotalBytesCached >= packetHeaderSize + topPacketHeader.TotalPayloadSize) { #region Handle Packet //We can either have exactly the right amount or even more than we were expecting //We may have too much data if we are sending high quantities and the packets have been concatenated SendReceiveOptions incomingPacketSendReceiveOptions = IncomingPacketSendReceiveOptions(topPacketHeader); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Debug("Received packet of type '" + topPacketHeader.PacketType + "' from " + ConnectionInfo + ", containing " + packetHeaderSize.ToString() + " header bytes and " + topPacketHeader.TotalPayloadSize.ToString() + " payload bytes."); bool isReservedPacketType = (topPacketHeader.PacketType != Enum.GetName(typeof(ReservedPacketType), ReservedPacketType.Unmanaged) && NetworkComms.ReservedPacketTypeNames.ContainsKey(topPacketHeader.PacketType)); //Get the packet sequence number if logging string packetSeqNumStr = ""; if (NetworkComms.LoggingEnabled) packetSeqNumStr = (topPacketHeader.ContainsOption(PacketHeaderLongItems.PacketSequenceNumber) ? ". pSeq#-" + topPacketHeader.GetOption(PacketHeaderLongItems.PacketSequenceNumber).ToString() + "." : ""); //Only reserved packet types get completed inline by default if (isReservedPacketType) { #if WINDOWS_PHONE || NETFX_CORE QueueItemPriority priority = QueueItemPriority.Normal; #else QueueItemPriority priority = (QueueItemPriority)Thread.CurrentThread.Priority; #endif PriorityQueueItem item = new PriorityQueueItem(priority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.TotalPayloadSize), incomingPacketSendReceiveOptions); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... handling packet type '" + topPacketHeader.PacketType + "' inline. Loop index - " + loopCounter.ToString() + packetSeqNumStr); NetworkComms.CompleteIncomingItemTask(item); } else { QueueItemPriority itemPriority = (incomingPacketSendReceiveOptions.Options.ContainsKey("ReceiveHandlePriority") ? (QueueItemPriority)Enum.Parse(typeof(QueueItemPriority), incomingPacketSendReceiveOptions.Options["ReceiveHandlePriority"]) : QueueItemPriority.Normal); PriorityQueueItem item = new PriorityQueueItem(itemPriority, this, topPacketHeader, packetBuilder.ReadDataSection(packetHeaderSize, topPacketHeader.TotalPayloadSize), incomingPacketSendReceiveOptions); //QueueItemPriority.Highest is the only priority that is executed inline if (itemPriority == QueueItemPriority.Highest) { if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... handling packet type '" + topPacketHeader.PacketType + "' with priority HIGHEST inline. Loop index - " + loopCounter.ToString() + packetSeqNumStr); NetworkComms.CompleteIncomingItemTask(item); } else { #if NETFX_CORE NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ") with priority " + itemPriority.ToString() + ". Loop index=" + loopCounter.ToString() + packetSeqNumStr); #else int threadId = NetworkComms.CommsThreadPool.EnqueueItem(item.Priority, NetworkComms.CompleteIncomingItemTask, item); if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace(" ... added completed " + item.PacketHeader.PacketType + " packet to thread pool (Q:" + NetworkComms.CommsThreadPool.QueueCount.ToString() + ", T:" + NetworkComms.CommsThreadPool.CurrentNumTotalThreads.ToString() + ", I:" + NetworkComms.CommsThreadPool.CurrentNumIdleThreads.ToString() + ") with priority " + itemPriority.ToString() + (threadId > 0 ? ". Selected threadId=" + threadId.ToString() : "") + ". Loop index=" + loopCounter.ToString() + packetSeqNumStr); #endif } } //We clear the bytes we have just handed off if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Trace("Removing " + (packetHeaderSize + topPacketHeader.TotalPayloadSize).ToString() + " bytes from incoming packet builder from connection with " + ConnectionInfo +"."); packetBuilder.ClearNTopBytes(packetHeaderSize + topPacketHeader.TotalPayloadSize); //Reset the expected bytes to 0 so that the next check starts from scratch packetBuilder.TotalBytesExpected = 0; //If we have run out of data completely then we can return immediately if (packetBuilder.TotalBytesCached == 0) return; #endregion } else throw new CommunicationException("This should be impossible!"); } loopCounter++; } } catch (Exception ex) { //Any error, throw an exception. if (NetworkComms.LoggingEnabled) NetworkComms.Logger.Fatal("A fatal exception occurred in IncomingPacketHandleHandOff(), connection with " + ConnectionInfo + " be closed. See log file for more information."); if (this is IPConnection) { //Log the exception in DOS protection if enabled if (IPConnection.DOSProtection.Enabled && ConnectionInfo.RemoteEndPoint.GetType() == typeof(IPEndPoint)) IPConnection.DOSProtection.LogMalformedData(ConnectionInfo.RemoteIPEndPoint.Address); } LogTools.LogException(ex, "CommsError", "A fatal exception occurred in IncomingPacketHandleHandOff(), connection with " + ConnectionInfo + " be closed. Loop counter " + loopCounter.ToString() + ". Packet builder contained " + packetBuilder.TotalBytesCached + " total cached bytes."); CloseConnection(true, 45); } }
public Packet(PacketHeader Header) { _header = Header; }
/// <summary> /// Store the packet for possible later resends, and fill in the header we'll use to send it (populate with /// sequence ID, last acknowledged ID from remote with ackmask. /// </summary> /// <param name="context">Pipeline context, the reliability shared state is used here.</param> /// <param name="inboundBuffer">Buffer with packet data.</param> /// <param name="header">Packet header which will be populated.</param> /// <returns>Sequence ID assigned to this packet.</returns> public static unsafe int Write(NetworkPipelineContext context, InboundBufferVec inboundBuffer, ref PacketHeader header) { SharedContext *reliable = (SharedContext *)context.internalSharedProcessBuffer.GetUnsafePtr(); var sequence = (ushort)reliable->SentPackets.Sequence; if (!TryAquire(context.internalProcessBuffer, sequence)) { reliable->errorCode = ErrorCodes.OutgoingQueueIsFull; return((int)ErrorCodes.OutgoingQueueIsFull); } reliable->stats.PacketsSent++; header.SequenceId = sequence; header.AckedSequenceId = (ushort)reliable->ReceivedPackets.Sequence; header.AckMask = reliable->ReceivedPackets.AckMask; reliable->ReceivedPackets.Acked = reliable->ReceivedPackets.Sequence; // Attach our processing time of the packet we're acknowledging (time between receiving it and sending this ack) header.ProcessingTime = CalculateProcessingTime(context.internalSharedProcessBuffer, header.AckedSequenceId, context.timestamp); reliable->SentPackets.Sequence = (ushort)(reliable->SentPackets.Sequence + 1); SetHeaderAndPacket(context.internalProcessBuffer, sequence, header, inboundBuffer, context.timestamp); StoreTimestamp(context.internalSharedProcessBuffer, sequence, context.timestamp); return(sequence); }
/// <summary> /// Deserializes NetPacket object /// </summary> /// <param name="bytes">Data bytes</param> /// <returns>Length of bytes read</returns> public long Deserialize(byte[] bytes) { using (MemoryStream ms = new MemoryStream(bytes)) { this._header = new PacketHeader(); ms.Position = this._header.Deserialize(bytes); long len = ms.Length - ms.Position; int buffLen = (int)Math.Min(len, int.MaxValue); this._data = new byte[buffLen]; int offset = 0; while (offset < len) { offset += ms.Read(this._data, offset, buffLen); } return offset; } }
private void FinaliseOutput(BinaryWriter writer, uint frameCount) { // Rewind the stream to the beginning and find the first RoutingID.ServerInfo message // and RoutingID.Control message with a ControlMessageID.FrameCount ID. These should be // the first and second messages in the stream. // We'll limit searching to the first 5 messages. long serverInfoMessageStart = -1; long frameCountMessageStart = -1; writer.Flush(); // Extract the stream from the writer. The first stream may be a GZip stream, in which case we must // extract the stream that is writing to instead as we can't rewind compression streams // and we wrote the header raw. writer.BaseStream.Flush(); Stream outStream = null; CollationStream zipStream = writer.BaseStream as CollationStream; if (zipStream != null) { outStream = zipStream.BaseStream; zipStream.Flush(); } else { outStream = writer.BaseStream; } // Check we are allowed to seek the stream. if (!outStream.CanSeek) { // Stream does not support seeking. The frame count will not be fixed. return; } // Record the initial stream position to restore later. long restorePos = outStream.Position; outStream.Seek(0, SeekOrigin.Begin); long streamPos = 0; byte[] headerBuffer = new byte[PacketHeader.Size]; PacketHeader header = new PacketHeader(); byte[] markerValidationBytes = BitConverter.GetBytes(Tes.IO.Endian.ToNetwork(PacketHeader.PacketMarker)); byte[] markerBytes = new byte[markerValidationBytes.Length]; bool markerValid = false; int attemptsRemaining = 5; int byteReadLimit = 0; markerBytes[0] = 0; while ((frameCountMessageStart < 0 || serverInfoMessageStart < 0) && attemptsRemaining > 0 && outStream.CanRead) { --attemptsRemaining; markerValid = false; // Limit the number of bytes we try read in each attempt. byteReadLimit = 1024; while (byteReadLimit > 0) { --byteReadLimit; outStream.Read(markerBytes, 0, 1); if (markerBytes[0] == markerValidationBytes[0]) { markerValid = true; int i = 1; for (i = 1; markerValid && outStream.CanRead && i < markerValidationBytes.Length; ++i) { outStream.Read(markerBytes, i, 1); markerValid = markerValid && markerBytes[i] == markerValidationBytes[i]; } if (markerValid) { break; } else { // We've failed to fully validate the maker. However, we did read and validate // one byte in the marker, then continued reading until the failure. It's possible // that the last byte read, the failed byte, may be the start of the actual marker. // We check this below, and if so, we rewind the stream one byte in order to // start validation from there on the next iteration. We can ignore the byte if // it is does not match the first validation byte. We are unlikely to ever make this // match though. --i; // Go back to the last read byte. if (markerBytes[i] == markerValidationBytes[0]) { // Potentially the start of a new marker. Rewind the stream to attempt to validate it. outStream.Seek(-1, SeekOrigin.Current); } } } } if (markerValid && outStream.CanRead) { // Potential packet target. Record the stream position at the start of the marker. streamPos = outStream.Position - markerBytes.Length; outStream.Seek(streamPos, SeekOrigin.Begin); // Test the packet. int bytesRead = outStream.Read(headerBuffer, 0, headerBuffer.Length); if (bytesRead == headerBuffer.Length) { // Create a packet. if (header.Read(new NetworkReader(new MemoryStream(headerBuffer, false)))) { // Header is OK. Looking for RoutingID.Control if (header.RoutingID == (ushort)RoutingID.ServerInfo) { serverInfoMessageStart = streamPos; } else if (header.RoutingID == (ushort)RoutingID.Control) { // It's control message. Complete and validate the packet. // Read the header. Determine the expected size and read that much more data. PacketBuffer packet = new PacketBuffer(header.PacketSize + Crc16.CrcSize); packet.Emplace(headerBuffer, bytesRead); packet.Emplace(outStream, header.PacketSize + Crc16.CrcSize - bytesRead); if (packet.Status == PacketBufferStatus.Complete) { // Packet complete. Extract the control message. NetworkReader packetReader = new NetworkReader(packet.CreateReadStream(true)); ControlMessage message = new ControlMessage(); if (message.Read(packetReader) && header.MessageID == (ushort)ControlMessageID.FrameCount) { // Found the message location. frameCountMessageStart = streamPos; } } } else { // At this point, we've failed to find the right kind of header. We could use the payload size to // skip ahead in the stream which should align exactly to the next message. // Not done for initial testing. } } } } } if (serverInfoMessageStart >= 0) { // Found the correct location. Seek the stream to here and write a new FrameCount control message. outStream.Seek(serverInfoMessageStart, SeekOrigin.Begin); PacketBuffer packet = new PacketBuffer(); header = PacketHeader.Create((ushort)RoutingID.ServerInfo, 0); packet.WriteHeader(header); _serverInfo.Write(packet); packet.FinalisePacket(); BinaryWriter patchWriter = new Tes.IO.NetworkWriter(outStream); packet.ExportTo(patchWriter); patchWriter.Flush(); } if (frameCountMessageStart >= 0) { // Found the correct location. Seek the stream to here and write a new FrameCount control message. outStream.Seek(frameCountMessageStart, SeekOrigin.Begin); PacketBuffer packet = new PacketBuffer(); ControlMessage frameCountMsg = new ControlMessage(); header = PacketHeader.Create((ushort)RoutingID.Control, (ushort)ControlMessageID.FrameCount); frameCountMsg.ControlFlags = 0; frameCountMsg.Value32 = frameCount; // Placeholder. Frame count is currently unknown. frameCountMsg.Value64 = 0; packet.WriteHeader(header); frameCountMsg.Write(packet); packet.FinalisePacket(); BinaryWriter patchWriter = new Tes.IO.NetworkWriter(outStream); packet.ExportTo(patchWriter); patchWriter.Flush(); } if (outStream.Position != restorePos) { outStream.Seek(restorePos, SeekOrigin.Begin); } }
/// <summary> /// Write packet, packet header and tracking information to the given buffer space. This buffer /// should contain the reliability Context at the front, that contains the capacity of the buffer /// and pointer offsets needed to find the slots we can copy the packet to. /// </summary> /// <param name="self">Buffer space where we can store packets.</param> /// <param name="sequence">The sequence ID of the packet, this is used to find a slot inside the buffer.</param> /// <param name="header">The packet header which we'll store with the packet payload.</param> /// <param name="data">The packet data which we're storing.</param> /// <exception cref="OverflowException"></exception> public static unsafe void SetHeaderAndPacket(NativeSlice <byte> self, int sequence, PacketHeader header, InboundBufferVec data, long timestamp) { byte * ptr = (byte *)self.GetUnsafePtr(); Context *ctx = (Context *)ptr; int totalSize = data.buffer1.Length + data.buffer2.Length; if (totalSize > ctx->DataStride) #if ENABLE_UNITY_COLLECTIONS_CHECKS { throw new OverflowException(); } #else { return; } #endif var index = sequence % ctx->Capacity; PacketInformation *info = GetPacketInformation(self, sequence); info->SequenceId = sequence; info->Size = totalSize; info->SendTime = timestamp; Packet *packet = GetPacket(self, sequence); packet->Header = header; var offset = (ctx->DataPtrOffset + (index * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>(); void *dataPtr = (ptr + offset); if (data.buffer1.Length > 0) { UnsafeUtility.MemCpy(dataPtr, data.buffer1.GetUnsafeReadOnlyPtr(), data.buffer1.Length); } if (data.buffer2.Length > 0) { UnsafeUtility.MemCpy(&dataPtr + data.buffer1.Length, data.buffer2.GetUnsafeReadOnlyPtr(), data.buffer2.Length); } }
protected void WhenBetAccepted(PacketHeader packetHeader, Connection connection, Packet05Bet incomingObject) { throw new NotImplementedException(); }
protected void WhenShowCards(PacketHeader packetHeader, Connection connection, Packet07Deck pack) { Console.WriteLine(pack.Descr); }
protected void WhenWaitGameAnswer(PacketHeader packetHeader, Connection connection, Packet04WaitGameAnswer incomingObject) { throw new NotImplementedException(); }
protected void WhenFirstBetRequest(PacketHeader packetHeader, Connection connection, Packet05Bet incomingObject) { }
protected void WhenPing(PacketHeader header, Connection connection, Packet00Message packet) { client.Login(); }
private void ReplyTurnContext(PacketHeader header, Connection connection, PlayerAction incomingMessage) { action = incomingMessage; }
public void SetSize(PacketHeader header, Connection connection, List <int> rt) { bp = new Bitmap(rt[0], rt[1], PixelFormat.Format24bppRgb); }
public void OnReceiveData(byte[] data, IPEndPoint ipEndpoint) { PacketHeader header = new PacketHeader(); MemoryStream stream = new MemoryStream(data); BinaryReader binaryReader = new BinaryReader(stream); int hash32 = binaryReader.ReadInt32(); byte[] dataWithoutHash = new byte[data.Length - 4]; Array.Copy(data, 4, dataWithoutHash, 0, data.Length - 4); #if DEBUG_CHECKSUM if (UnityEngine.Random.Range(0f, 100f) < 0.5f) { if (dataWithoutHash[0] != 0) { dataWithoutHash[0] = 0; } else { dataWithoutHash[0] = 1; } } #endif int ourHash; using (MD5 md5Hash = MD5.Create()) { byte[] hash = md5Hash.ComputeHash(dataWithoutHash); MemoryStream hashStream = new MemoryStream(hash); BinaryReader hashReader = new BinaryReader(hashStream); ourHash = hashReader.ReadInt32(); hashStream.Close(); } if (hash32 == ourHash) { bool reliability = binaryReader.ReadBoolean(); if (reliability) { #if DEBUG_RELIABLE if (UnityEngine.Random.Range(0f, 100f) < 0.6f) { // if (Input.GetKey(KeyCode.A)) { stream.Close(); return; } #endif uint packageAck = binaryReader.ReadUInt32(); if (ConnectionManager.Instance.isServer) { Client client = ConnectionManager.Instance.clients[ConnectionManager.Instance.ipToId[ipEndpoint]]; client.ackChecker.RegisterPackageReceived(packageAck); } else { ConnectionManager.Instance.OwnClient.ackChecker.RegisterPackageReceived(packageAck); } bool hasAck = binaryReader.ReadBoolean(); if (hasAck) { uint lastAck = binaryReader.ReadUInt32(); uint prevAckArray = binaryReader.ReadUInt32(); if (ConnectionManager.Instance.isServer) { Client client = ConnectionManager.Instance.clients[ConnectionManager.Instance.ipToId[ipEndpoint]]; client.ackChecker.ClearPackets(lastAck, prevAckArray); } else { ConnectionManager.Instance.OwnClient.ackChecker.ClearPackets(lastAck, prevAckArray); } } } header.Deserialize(stream); if (header.packetType == PacketType.User) { while (stream.Length - stream.Position > 0) { UserPacketHeader userHeader = new UserPacketHeader(); userHeader.Deserialize(stream); InvokeCallback(userHeader.objectId, userHeader.packetType, stream); } } else { ConnectionManager.Instance.OnReceivePacket(ipEndpoint, header.packetType, stream); } } else { Debug.LogWarning("PACKAGE CORRUPTED"); } stream.Close(); }
private void OnRemoteEvent(PacketHeader packetHeader, Connection connection, NetworkEvent incomingObject) { RemoteEventReceived?.Invoke(this, incomingObject.EventKey); }
private void HandleIncomingCommandManagingSystem(PacketHeader packetHeader, Connection connection, VRCommandServer vrCommandServer) { OperationInfo opInfo = new OperationInfo() { SourceType = Enums.SourceType.MANAGEMENT_SYSTEM, ConnectionInfo = connection.ConnectionInfo }; switch (vrCommandServer.ControlMessage) { case VRGameSelectorServerDTO.Enums.ControlMessage.NONE: break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_SYSCONFIG: GetSysConfig(connection.ConnectionInfo, vrCommandServer.SystemConfig); break; case VRGameSelectorServerDTO.Enums.ControlMessage.SET_SYSCONFIG: SetSysConfig(vrCommandServer.SystemConfig); UpdateAllClientDaemonSystemConfig(); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_CONFIGED_CLIENT_LIST: GetConfiguredClientList(connection.ConnectionInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.MODIFY_CLIENT_CONFIG: ModifyClientConfig(connection.ConnectionInfo, vrCommandServer.Client); break; case VRGameSelectorServerDTO.Enums.ControlMessage.ADD_CLIENT_CONFIG: AddClientConfig(connection.ConnectionInfo, vrCommandServer.Client); break; case VRGameSelectorServerDTO.Enums.ControlMessage.DELETE_CLIENT_CONFIG: DeleteClientConfig(connection.ConnectionInfo, vrCommandServer.Client); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_CONFIG_SET_LIST: GetConfigSetList(connection.ConnectionInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.MODIFY_CONFIG_SET: ModifyConfigSetList(connection.ConnectionInfo, vrCommandServer.ConfigSet); break; case VRGameSelectorServerDTO.Enums.ControlMessage.ADD_CONFIG_SET: AddConfigSetList(connection.ConnectionInfo, vrCommandServer.ConfigSet); break; case VRGameSelectorServerDTO.Enums.ControlMessage.DELETE_CONFIG_SET: DeleteConfigSetList(connection.ConnectionInfo, vrCommandServer.ConfigSet); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_TILE_CONFIG: GetTileConfigList(connection.ConnectionInfo, vrCommandServer.TileConfig.TileConfigSetID); break; case VRGameSelectorServerDTO.Enums.ControlMessage.MODIFY_TILE_CONFIG: ModifyTileConfig(connection.ConnectionInfo, vrCommandServer.TileConfig); break; case VRGameSelectorServerDTO.Enums.ControlMessage.ADD_TILE_CONFIG: AddTileConfig(connection.ConnectionInfo, vrCommandServer.TileConfig); break; case VRGameSelectorServerDTO.Enums.ControlMessage.DELETE_TILE_CONFIG: DeleteTileConfig(connection.ConnectionInfo, vrCommandServer.TileConfig); break; case VRGameSelectorServerDTO.Enums.ControlMessage.REORDER_UP_TILE_CONFIG: ReorderUpTileConfig(connection.ConnectionInfo, vrCommandServer.TileConfig); break; case VRGameSelectorServerDTO.Enums.ControlMessage.REORDER_DOWN_TILE_CONFIG: ReorderDownTileConfig(connection.ConnectionInfo, vrCommandServer.TileConfig); break; case Enums.ControlMessage.SYNC_TILE_CONFIG: UpdateAllClientDaemonTileConfig(); break; case Enums.ControlMessage.REINIT_CLIENT_SETTING: BuildInternalClientStatus(); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_LIVE_SYSTEM_INFO: SendLiveSystemInfoToManagingSystem(connection.ConnectionInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.START_TIMING: SendStartTiming(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.START_NOW: SendStartNow(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.END_NOW: SendEndNow(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.REBOOT: SendReboot(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.TURN_OFF: SendTurnOff(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.TURN_OFF_KMU: SendTurnOffKMU(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.TURN_ON_KMU: SendTurnOnKMU(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.HELP_PROVIDED: ResetHelpRequestStatus(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.CLEANING_PROVIDED: ResetCleaningStatus(vrCommandServer.ClientParm, opInfo); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GET_GAME_PLAY_HISTORY: GetGamePlayHistory(connection.ConnectionInfo, vrCommandServer.ClientParm); break; case VRGameSelectorServerDTO.Enums.ControlMessage.GENERATE_BARCODE: GenerateBarcode(connection.ConnectionInfo, vrCommandServer.BarcodeInfo); break; case Enums.ControlMessage.GET_KEY: GetKey(connection.ConnectionInfo); break; case Enums.ControlMessage.DELETE_KEY: DeleteKey(connection.ConnectionInfo, vrCommandServer.ListKeyInfo); break; case Enums.ControlMessage.ADD_KEY: AddKey(connection.ConnectionInfo, vrCommandServer.ListKeyInfo); break; case Enums.ControlMessage.GET_KEY_TYPE: GetKeyType(connection.ConnectionInfo); break; case Enums.ControlMessage.GET_PENDING_WAIVER: GetPendingWaiverList(connection.ConnectionInfo); break; case Enums.ControlMessage.GET_BOOKING_REF_SETTING: GetBookingReferenceSetting(connection.ConnectionInfo, vrCommandServer.BookingReference); break; case Enums.ControlMessage.DELETE_PENDING_WAIVER: DeletePendingWaiver(connection.ConnectionInfo, vrCommandServer.ListWaiverInfo); break; case Enums.ControlMessage.MARK_WAIVER_RECEIVED: MarkWaiverReceived(connection.ConnectionInfo, vrCommandServer.ListWaiverInfo); break; default: break; } }
private void Reply(PacketHeader header, Connection connection, string incomingMessage) { waitPlayer = true; }
/// <summary> /// Handles an incoming packet of type 'PartialFileDataInfo' /// </summary> /// <param name="header">Header associated with incoming packet</param> /// <param name="connection">The connection associated with incoming packet</param> /// <param name="data">The incoming data automatically converted to a SendInfo object</param> private void IncomingPartialFileDataInfo(PacketHeader header, Connection connection, SendInfo info) { try { byte[] data = null; ReceivedFile file = null; //Perform this in a thread safe way lock (syncRoot) { //Extract the packet sequence number from the header //The header can also user defined parameters long sequenceNumber = info.PacketSequenceNumber; if (incomingDataCache.ContainsKey(connection.ConnectionInfo) && incomingDataCache[connection.ConnectionInfo].ContainsKey(sequenceNumber)) { //We already have the associated data in the cache data = incomingDataCache[connection.ConnectionInfo][sequenceNumber]; incomingDataCache[connection.ConnectionInfo].Remove(sequenceNumber); //Check to see if we have already received any files from this location if (!receivedFilesDict.ContainsKey(connection.ConnectionInfo)) { receivedFilesDict.Add(connection.ConnectionInfo, new Dictionary <string, ReceivedFile>()); } //Check to see if we have already initialised this file if (!receivedFilesDict[connection.ConnectionInfo].ContainsKey(info.Filename)) { receivedFilesDict[connection.ConnectionInfo].Add(info.Filename, new ReceivedFile(info.Filename, connection.ConnectionInfo, info.TotalBytes)); AddNewReceivedItem(receivedFilesDict[connection.ConnectionInfo][info.Filename]); } file = receivedFilesDict[connection.ConnectionInfo][info.Filename]; } else { //We do not yet have the necessary data corresponding with this SendInfo so we add the //info to the cache if (!incomingDataInfoCache.ContainsKey(connection.ConnectionInfo)) { incomingDataInfoCache.Add(connection.ConnectionInfo, new Dictionary <long, SendInfo>()); } incomingDataInfoCache[connection.ConnectionInfo].Add(sequenceNumber, info); } } //If we have everything we need we can add data to the ReceivedFile if (data != null && file != null && !file.IsCompleted) { file.AddData(info.BytesStart, 0, data.Length, data); //Perform a little clean-up file = null; data = null; GC.Collect(); } else if (data == null ^ file == null) { throw new Exception("Either both are null or both are set. Data is " + (data == null ? "null." : "set.") + " File is " + (file == null ? "null." : "set.") + " File is " + (file.IsCompleted ? "completed." : "not completed.")); } } catch (Exception ex) { //If an exception occurs we write to the log window and also create an error file AddLineToLog("Exception - " + ex.ToString()); LogTools.LogException(ex, "IncomingPartialFileDataInfo"); } }
private static void PrintIncomingMessage(PacketHeader header, Connection connection, string message) { Console.WriteLine(message); }
/// <summary> /// Resend a packet which we have not received an acknowledgement for in time. Pipeline resume /// will be enabled if there are more packets which we need to resend. The send reliability context /// will then also be updated to track the next packet we need to resume. /// </summary> /// <param name="context">Pipeline context, we'll use both the shared reliability context and send context.</param> /// <param name="header">Packet header for the packet payload we're resending.</param> /// <param name="needsResume">Indicates if a pipeline resume is needed again.</param> /// <returns>Buffer slice to packet payload.</returns> /// <exception cref="ApplicationException"></exception> public static unsafe NativeSlice <byte> ResumeSend(NetworkPipelineContext context, out PacketHeader header, ref bool needsResume) { SharedContext *reliable = (SharedContext *)context.internalSharedProcessBuffer.GetUnsafePtr(); Context * ctx = (Context *)context.internalProcessBuffer.GetUnsafePtr(); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (ctx->Resume == NullEntry) { throw new ApplicationException("This function should not be called unless there is data in resume"); } #endif var sequence = (ushort)ctx->Resume; PacketInformation *information; information = GetPacketInformation(context.internalProcessBuffer, sequence); // Reset the resend timer information->SendTime = context.timestamp; Packet *packet = GetPacket(context.internalProcessBuffer, sequence); header = packet->Header; // Update acked/ackmask to latest values header.AckedSequenceId = (ushort)reliable->ReceivedPackets.Sequence; header.AckMask = reliable->ReceivedPackets.AckMask; var offset = (ctx->DataPtrOffset + ((sequence % ctx->Capacity) * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>(); NativeSlice <byte> slice = new NativeSlice <byte>(context.internalProcessBuffer, offset, information->Size); reliable->stats.PacketsResent++; needsResume = false; ctx->Resume = -1; // Check if another packet needs to be resent right after this one for (int i = sequence + 1; i < reliable->ReceivedPackets.Sequence + 1; i++) { var timeToResend = CurrentResendTime(context.internalSharedProcessBuffer); information = GetPacketInformation(context.internalProcessBuffer, i); if (information->SequenceId >= 0 && information->SendTime + timeToResend > context.timestamp) { needsResume = true; ctx->Resume = i; } } return(slice); }
/// <summary> /// Constructor /// </summary> public NetPacket() { this._data = null; this._header = null; }
/// <summary> /// Read header data and update reliability tracking information in the shared context. /// - If the packets sequence ID is lower than the last received ID+1, then it's stale /// - If the packets sequence ID is higher, then we'll process it and update tracking info in the shared context /// </summary> /// <param name="context">Pipeline context, the reliability shared state is used here.</param> /// <param name="header">Packet header of a new received packet.</param> /// <returns>Sequence ID of the received packet.</returns> public static unsafe int Read(NetworkPipelineContext context, PacketHeader header) { SharedContext *reliable = (SharedContext *)context.internalSharedProcessBuffer.GetUnsafePtr(); reliable->stats.PacketsReceived++; if (SequenceHelpers.StalePacket( header.SequenceId, (ushort)(reliable->ReceivedPackets.Sequence + 1), (ushort)reliable->WindowSize)) { reliable->stats.PacketsStale++; return((int)ErrorCodes.Stale_Packet); } var window = reliable->WindowSize - 1; if (SequenceHelpers.GreaterThan16((ushort)(header.SequenceId + 1), (ushort)reliable->ReceivedPackets.Sequence)) { int distance = SequenceHelpers.AbsDistance(header.SequenceId, (ushort)reliable->ReceivedPackets.Sequence); for (var i = 0; i < Math.Min(distance, window); ++i) { if ((reliable->ReceivedPackets.AckMask & 1 << (window - i)) == 0) { reliable->stats.PacketsDropped++; } } if (distance > window) { reliable->stats.PacketsDropped += distance - window; reliable->ReceivedPackets.AckMask = 1; } else { reliable->ReceivedPackets.AckMask <<= distance; reliable->ReceivedPackets.AckMask |= 1; } reliable->ReceivedPackets.Sequence = header.SequenceId; } else if (SequenceHelpers.LessThan16(header.SequenceId, (ushort)reliable->ReceivedPackets.Sequence)) { int distance = SequenceHelpers.AbsDistance(header.SequenceId, (ushort)reliable->ReceivedPackets.Sequence); // If this is a resent packet the distance will seem very big and needs to be calculated again with adjustment for wrapping if (distance >= ushort.MaxValue - reliable->WindowSize) { distance = reliable->ReceivedPackets.Sequence - header.SequenceId; } var ackBit = 1 << distance; if ((ackBit & reliable->ReceivedPackets.AckMask) != 0) { reliable->stats.PacketsDuplicated++; return((int)ErrorCodes.Duplicated_Packet); } reliable->stats.PacketsOutOfOrder++; reliable->ReceivedPackets.AckMask |= (uint)ackBit; } // Store receive timestamp for remote sequence ID we just received StoreRemoteReceiveTimestamp(context.internalSharedProcessBuffer, header.SequenceId, context.timestamp); ReadAckPacket(context, header); return(header.SequenceId); }
/// <summary> /// Constructor /// </summary> /// <param name="src">Source Id</param> /// <param name="dest">Destination Id</param> /// <param name="data">Data bytes</param> public NetPacket(int src, int dest, byte[] data) { this._header = new PacketHeader(src, dest, PacketType.Print); this._data = data; }
public PacketMotionData(PacketHeader packetHeader) { Header = packetHeader; }
public void GetID(PacketHeader header, Connection connection, uint id) { this.id = id; }
public PacketHandlerAttribute(PacketHeader methodId, string name, int size, PacketDirection direction) { this.MethodId = (ushort) methodId; this.Name = name; this.Size = size; this.Direction = direction; }
void DoDefualutHandler(PacketHeader header, C2PayloadVector payload, C2Session session) { throw new NotImplementedException(); }
internal ClientProtocol(Connection dtc) : base(dtc) { _packet = new PacketHeader(); _output = new StorageWriter(null); _source = new StorageReader(null); }
/// <summary> /// The handler that we wish to execute when we receive a message packet. /// </summary> /// <param name="header">The associated packet header.</param> /// <param name="connection">The connection used for the incoming packet</param> /// <param name="incomingString">The incoming data converted to a string</param> private static void HandleIncomingMessagePacket(PacketHeader header, Connection connection, string incomingString) { Console.WriteLine("\n ... Incoming message from " + connection.ToString() + " saying '" + incomingString + "'."); }
private static void PrintIncomingMessage(PacketHeader header, Connection connection, string message) { Console.WriteLine(connection.ToString() + " said '" + message + "'."); }
private void PrintIncomingMessage(PacketHeader header, Connection connection, string message) { MessageString = message; Tokennum = header.PacketType; }
public PendingPacket(PacketHeader header) { this.header = header; this.buffer = new ByteArray(); this.buffer.Compressed = header.Compressed; }
public PacketAttribute(PacketHeader header) { Header = header; }
private void AddLineToPacketHeaderDataGridView(DataGridView dataGridView, DataGridViewRow row, PacketHeader header, string magic) { int counter = 3; foreach (var field in header.GetType().GetFields()) { bool magicField = field.Name.Equals("h_magic", StringComparison.Ordinal); if (magicField) { row.Cells[counter].Value = magic; } else { string value = field.GetValue(header).ToString(); row.Cells[counter].Value = value; } counter++; } dataGridView.Rows.Add(row); }
/// <exception cref="System.IO.IOException"/> private int ReadChunkImpl(long pos, byte[] buf, int offset, int len, byte[] checksumBuf ) { lock (this) { // Read one chunk. if (eos) { // Already hit EOF return(-1); } // Read one DATA_CHUNK. long chunkOffset = lastChunkOffset; if (lastChunkLen > 0) { chunkOffset += lastChunkLen; } // pos is relative to the start of the first chunk of the read. // chunkOffset is relative to the start of the block. // This makes sure that the read passed from FSInputChecker is the // for the same chunk we expect to be reading from the DN. if ((pos + firstChunkOffset) != chunkOffset) { throw new IOException("Mismatch in pos : " + pos + " + " + firstChunkOffset + " != " + chunkOffset); } // Read next packet if the previous packet has been read completely. if (dataLeft <= 0) { //Read packet headers. PacketHeader header = new PacketHeader(); header.ReadFields(@in); if (Log.IsDebugEnabled()) { Log.Debug("DFSClient readChunk got header " + header); } // Sanity check the lengths if (!header.SanityCheck(lastSeqNo)) { throw new IOException("BlockReader: error in packet header " + header); } lastSeqNo = header.GetSeqno(); dataLeft = header.GetDataLen(); AdjustChecksumBytes(header.GetDataLen()); if (header.GetDataLen() > 0) { IOUtils.ReadFully(@in, ((byte[])checksumBytes.Array()), 0, checksumBytes.Limit()); } } // Sanity checks System.Diagnostics.Debug.Assert(len >= bytesPerChecksum); System.Diagnostics.Debug.Assert(checksum != null); System.Diagnostics.Debug.Assert(checksumSize == 0 || (checksumBuf.Length % checksumSize == 0)); int checksumsToRead; int bytesToRead; if (checksumSize > 0) { // How many chunks left in our packet - this is a ceiling // since we may have a partial chunk at the end of the file int chunksLeft = (dataLeft - 1) / bytesPerChecksum + 1; // How many chunks we can fit in databuffer // - note this is a floor since we always read full chunks int chunksCanFit = Math.Min(len / bytesPerChecksum, checksumBuf.Length / checksumSize ); // How many chunks should we read checksumsToRead = Math.Min(chunksLeft, chunksCanFit); // How many bytes should we actually read bytesToRead = Math.Min(checksumsToRead * bytesPerChecksum, dataLeft); } else { // full chunks // in case we have a partial // no checksum bytesToRead = Math.Min(dataLeft, len); checksumsToRead = 0; } if (bytesToRead > 0) { // Assert we have enough space System.Diagnostics.Debug.Assert(bytesToRead <= len); System.Diagnostics.Debug.Assert(checksumBytes.Remaining() >= checksumSize * checksumsToRead ); System.Diagnostics.Debug.Assert(checksumBuf.Length >= checksumSize * checksumsToRead ); IOUtils.ReadFully(@in, buf, offset, bytesToRead); checksumBytes.Get(checksumBuf, 0, checksumSize * checksumsToRead); } dataLeft -= bytesToRead; System.Diagnostics.Debug.Assert(dataLeft >= 0); lastChunkOffset = chunkOffset; lastChunkLen = bytesToRead; // If there's no data left in the current packet after satisfying // this read, and we have satisfied the client read, we expect // an empty packet header from the DN to signify this. // Note that pos + bytesToRead may in fact be greater since the // DN finishes off the entire last chunk. if (dataLeft == 0 && pos + bytesToRead >= bytesNeededToFinish) { // Read header PacketHeader hdr = new PacketHeader(); hdr.ReadFields(@in); if (!hdr.IsLastPacketInBlock() || hdr.GetDataLen() != 0) { throw new IOException("Expected empty end-of-read packet! Header: " + hdr); } eos = true; } if (bytesToRead == 0) { return(-1); } return(bytesToRead); } }