public override void Start() { base.Start(); if (Sending) { ushort packNum = ++base.P2PSession.Bridge.PackageNo; // Data prep P2PDataMessage prepData = new P2PDataMessage(P2PVersion); prepData.WritePreparationBytes(); if (P2PVersion == P2PVersion.P2PV2) { prepData.V2Header.TFCombination = TFCombination.First; } SendMessage(prepData); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Data prep sent. Sending whole data...", GetType().Name); // All chunks byte[] allData = new byte[msnObject.Size]; lock (objStream) { using (Stream s = objStream) { s.Position = 0; s.Read(allData, 0, allData.Length); } } P2PDataMessage msg = new P2PDataMessage(P2PVersion); if (P2PVersion == P2PVersion.P2PV1) { msg.V1Header.Flags = P2PFlag.Data; msg.V1Header.AckSessionId = (uint)new Random().Next(50, int.MaxValue); } else if (P2PVersion == P2PVersion.P2PV2) { msg.V2Header.TFCombination = TFCombination.MsnObject | TFCombination.First; msg.V2Header.PackageNumber = packNum; } msg.InnerBody = allData; if (P2PVersion == P2PVersion.P2PV1) { // Object transfer must be finish in MaxTimeout seconds. (p2pv1) // Because ack is received after transfer finished. SendMessage(msg, P2PBridge.MaxTimeout, delegate(P2PMessage ack) { OnTransferFinished(EventArgs.Empty); // Close after remote client sends BYE. }); } else { SendMessage(msg, 0, null); // Register the ACKHandler P2PMessage rak = new P2PMessage(P2PVersion); SendMessage(rak, P2PBridge.DefaultTimeout, delegate(P2PMessage ack) { OnTransferFinished(EventArgs.Empty); // Close after remote client sends BYE. }); } } else { objStream = new MemoryStream(); } }
public override void Start() { base.Start(); if (sending) { if (activityData != string.Empty && activityData != null) { activityData += "\0"; int urlLength = Encoding.Unicode.GetByteCount(activityData); // Data prep MemoryStream urlDataStream = new MemoryStream(); P2PDataMessage prepData = new P2PDataMessage(P2PVersion); byte[] header = (P2PVersion == P2PVersion.P2PV1) ? new byte[] { 0x80, 0x00, 0x00, 0x00 } : new byte[] { 0x80, 0x3f, 0x14, 0x05 }; urlDataStream.Write(header, 0, header.Length); urlDataStream.Write(BitUtility.GetBytes((ushort)0x08, true), 0, sizeof(ushort)); //data type: 0x08: string urlDataStream.Write(BitUtility.GetBytes(urlLength, true), 0, sizeof(int)); urlDataStream.Write(Encoding.Unicode.GetBytes(activityData), 0, urlLength); urlDataStream.Seek(0, SeekOrigin.Begin); byte[] urlData = urlDataStream.ToArray(); urlDataStream.Close(); prepData.InnerBody = urlData; if (P2PVersion == P2PVersion.P2PV2) { prepData.V2Header.TFCombination = TFCombination.First; } SendMessage(prepData); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Data sent...", GetType().Name); } } }
private void SendChunk() { if (!_sendingData) return; P2PDataMessage p2pChunk = new P2PDataMessage(P2PVersion); long offset = _dataStream.Position; // First chunk if (offset == 0) { if (P2PVersion == P2PVersion.P2PV1) { P2PSession.IncreaseLocalIdentifier(); p2pChunk.V1Header.TotalSize = (ulong)_dataStream.Length; } else if (P2PVersion == P2PVersion.P2PV2) { p2pChunk.V2Header.TFCombination = TFCombination.First; } } p2pChunk.Header.Identifier = P2PSession.LocalIdentifier; p2pChunk.WriteBytes(_dataStream, P2PSession.Bridge.MaxDataSize); AckHandler ackHandler = null; int ackTimeout = P2PBridge.MaxTimeout; if (P2PVersion == P2PVersion.P2PV1) { p2pChunk.V1Header.Flags = P2PFlag.FileData; } else if (P2PVersion == P2PVersion.P2PV2) { p2pChunk.V2Header.PackageNumber = packNum; p2pChunk.V2Header.TFCombination |= TFCombination.FileTransfer; if (p2pv2NextRAK < DateTime.Now) { _sendingData = false; // Activate when ack received. p2pChunk.V2Header.OperationCode |= (byte)OperationCode.RAK; p2pv2NextRAK = DateTime.Now.AddSeconds(8); ackTimeout = P2PBridge.DefaultTimeout; ackHandler = delegate(P2PMessage ack) { _sendingData = true; // Ack received, continue sending... SendChunk(); }; } } if (_dataStream.Position == _dataStream.Length) { _sendingData = false; SendMessage(p2pChunk); // This is the last chunk of data, register the ACKHandler P2PMessage rak = new P2PMessage(P2PVersion); SendMessage(rak, P2PBridge.DefaultTimeout, delegate(P2PMessage ack) { Abort(); OnTransferFinished(EventArgs.Empty); }); } else { SendMessage(p2pChunk, ackTimeout, ackHandler); } OnProgressed(EventArgs.Empty); }