Esempio n. 1
0
            /// <summary>
            /// Sends the specified packet to this node.
            /// </summary>
            /// <param name="packet">The packet to send.</param>
            public void SendData(INodePacket packet)
            {
                MemoryStream writeStream     = new MemoryStream();
                ITranslator  writeTranslator = BinaryTranslator.GetWriteTranslator(writeStream);

                try
                {
                    writeStream.WriteByte((byte)packet.Type);

                    // Pad for the packet length
                    writeStream.Write(BitConverter.GetBytes((int)0), 0, 4);
                    packet.Translate(writeTranslator);

                    // Now plug in the real packet length
                    writeStream.Position = 1;
                    writeStream.Write(BitConverter.GetBytes((int)writeStream.Length - 5), 0, 4);

                    byte[] writeStreamBuffer = writeStream.GetBuffer();

                    for (int i = 0; i < writeStream.Length; i += MaxPacketWriteSize)
                    {
                        int lengthToWrite = Math.Min((int)writeStream.Length - i, MaxPacketWriteSize);
                        if ((int)writeStream.Length - i <= MaxPacketWriteSize)
                        {
                            // We are done, write the last bit asynchronously.  This is actually the general case for
                            // most packets in the build, and the asynchronous behavior here is desirable.
#if FEATURE_APM
                            _serverToClientStream.BeginWrite(writeStreamBuffer, i, lengthToWrite, PacketWriteComplete, null);
#else
                            _serverToClientStream.WriteAsync(writeStreamBuffer, i, lengthToWrite);
#endif
                            return;
                        }
                        else
                        {
                            // If this packet is longer that we can write in one go, then we need to break it up.  We can't
                            // return out of this function and let the rest of the system continue because another operation
                            // might want to send data immediately afterward, and that could result in overlapping writes
                            // to the pipe on different threads.
#if FEATURE_APM
                            IAsyncResult result = _serverToClientStream.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, null, null);
                            _serverToClientStream.EndWrite(result);
#else
                            _serverToClientStream.Write(writeStreamBuffer, i, lengthToWrite);
#endif
                        }
                    }
                }
                catch (IOException e)
                {
                    // Do nothing here because any exception will be caught by the async read handler
                    CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e);
                }
                catch (ObjectDisposedException) // This happens if a child dies unexpectedly
                {
                    // Do nothing here because any exception will be caught by the async read handler
                }
            }
Esempio n. 2
0
            /// <summary>
            /// Actually writes and sends the packet. This can't be called in parallel
            /// because it reuses the _writeBufferMemoryStream, and this is why we use
            /// the _packetWriteDrainTask to serially chain invocations one after another.
            /// </summary>
            /// <param name="packet">The packet to send.</param>
            private void SendDataCore(INodePacket packet)
            {
                MemoryStream writeStream = _writeBufferMemoryStream;

                // clear the buffer but keep the underlying capacity to avoid reallocations
                writeStream.SetLength(0);

                ITranslator writeTranslator = BinaryTranslator.GetWriteTranslator(writeStream);

                try
                {
                    writeStream.WriteByte((byte)packet.Type);

                    // Pad for the packet length
                    WriteInt32(writeStream, 0);
                    packet.Translate(writeTranslator);

                    int writeStreamLength = (int)writeStream.Position;

                    // Now plug in the real packet length
                    writeStream.Position = 1;
                    WriteInt32(writeStream, writeStreamLength - 5);

                    byte[] writeStreamBuffer = writeStream.GetBuffer();

                    for (int i = 0; i < writeStreamLength; i += MaxPacketWriteSize)
                    {
                        int lengthToWrite = Math.Min(writeStreamLength - i, MaxPacketWriteSize);
                        _serverToClientStream.Write(writeStreamBuffer, i, lengthToWrite);
                    }
                    if (IsExitPacket(packet))
                    {
                        _exitPacketState = ExitPacketState.ExitPacketSent;
                    }
                }
                catch (IOException e)
                {
                    // Do nothing here because any exception will be caught by the async read handler
                    CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e);
                }
                catch (ObjectDisposedException) // This happens if a child dies unexpectedly
                {
                    // Do nothing here because any exception will be caught by the async read handler
                }
            }
Esempio n. 3
0
            /// <summary>
            /// Sends the specified packet to this node.
            /// </summary>
            /// <param name="packet">The packet to send.</param>
            public void SendData(INodePacket packet)
            {
                MemoryStream writeStream = new MemoryStream();
                INodePacketTranslator writeTranslator = NodePacketTranslator.GetWriteTranslator(writeStream);
                try
                {
                    writeStream.WriteByte((byte)packet.Type);

                    // Pad for the packet length
                    writeStream.Write(BitConverter.GetBytes((int)0), 0, 4);
                    packet.Translate(writeTranslator);

                    // Now plug in the real packet length
                    writeStream.Position = 1;
                    writeStream.Write(BitConverter.GetBytes((int)writeStream.Length - 5), 0, 4);

#if FALSE
                    if (trace) // Avoid method call
                    {
                        CommunicationsUtilities.Trace(nodeId, "Sending Packet of type {0} with length {1}", packet.Type.ToString(), writeStream.Length - 5);
                    }
#endif

                    for (int i = 0; i < writeStream.Length; i += MaxPacketWriteSize)
                    {
                        int lengthToWrite = Math.Min((int)writeStream.Length - i, MaxPacketWriteSize);
                        if ((int)writeStream.Length - i <= MaxPacketWriteSize)
                        {
                            // We are done, write the last bit asynchronously.  This is actually the general case for
                            // most packets in the build, and the asynchronous behavior here is desirable.
                            _nodePipe.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, PacketWriteComplete, null);
                            return;
                        }
                        else
                        {
                            // If this packet is longer that we can write in one go, then we need to break it up.  We can't
                            // return out of this function and let the rest of the system continue because another operation
                            // might want to send data immediately afterward, and that could result in overlapping writes
                            // to the pipe on different threads.
                            IAsyncResult result = _nodePipe.BeginWrite(writeStream.GetBuffer(), i, lengthToWrite, null, null);
                            _nodePipe.EndWrite(result);
                        }
                    }
                }
                catch (IOException e)
                {
                    // Do nothing here because any exception will be caught by the async read handler
                    CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e);
                }
                catch (ObjectDisposedException) // This happens if a child dies unexpectedly
                {
                    // Do nothing here because any exception will be caught by the async read handler
                }
            }