Ejemplo n.º 1
0
        /// <summary>
        /// Receives a message over a specified Duplex Channel Connection.
        /// </summary>
        /// <param name="connection">Duplex Channel Connection</param>
        /// <param name="ar">Result (for Async pattern)</param>
        /// <returns>Received message</returns>
        public static Message EndReceive(out Connection connection, IAsyncResult ar)
        {
            AsyncResult myAr = (AsyncResult)ar;

            connection = myAr.Connection;
            try
            {
                connection.LockRead();
                if (connection.Socket == null)
                {
                    throw new MessageException("Connection closed.", null, connection);
                }

                SocketError socketError;
                int         bytesRead = connection.Socket.EndReceive(myAr.InternalAsyncResult, out socketError);
                if (bytesRead == 0 || connection.Channel == null)
                {
                    throw new MessageException("Connection closed.", new SocketException((int)socketError), connection);
                }

                // read message identifier
                var reader = connection.Reader;
                if (bytesRead < SizeOfGuid)
                {
                    var rest = reader.Read(myAr.Buffer, bytesRead, SizeOfGuid - bytesRead);
                    if (rest < SizeOfGuid - bytesRead)
                    {
                        throw new MessageException("Insufficient data received. Got " + bytesRead + " bytes.", new SocketException((int)socketError), connection);
                    }
                }

                // read message header
                Message retVal = new Message();
                retVal.Guid = new Guid(myAr.Buffer);

                int          headerLength = reader.ReadInt32();
                MemoryStream headerStream = new MemoryStream(reader.ReadBytes(headerLength));
                if (headerStream.Length != headerLength)
                {
                    throw new Exception("Not enough headers read...");
                }
                retVal.Headers = TransportHeaderWrapper.Deserialize(headerStream);

                int bodyLength = reader.ReadInt32();
                if (bodyLength > 0)
                {
                    retVal.messageBodyBytes = reader.ReadBytes(bodyLength);
                    if (retVal.messageBodyBytes.Length != bodyLength)
                    {
                        throw new Exception("Not enough body read...");
                    }

                    System.Diagnostics.Debug.Assert(retVal.MessageBody.CanRead);
                }

                Message.BeginReceive(connection, myAr.Callback, myAr.AsyncState);
                return(retVal);
            }
            catch (Exception e)
            {
                throw new MessageException("Error receiving message", e, connection);
            }
            finally
            {
                connection.ReleaseRead();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sends a specified message over a specified connection.
        /// </summary>
        /// <param name="connection">Duplex Channel Connection</param>
        /// <param name="guid">Unique identifier of the Message</param>
        /// <param name="headers">Remoting transport headers</param>
        /// <param name="message">Stream with raw data of the message</param>
        public static void Send(Connection connection, Guid guid, ITransportHeaders headers, Stream message)
        {
            try
            {
                connection.LockWrite();
                BinaryWriter writer = connection.Writer;

                if (writer == null)
                {
                    // Unexpected connection loss. Connection isn´t working anymore, so close it.
                    connection.ReleaseWrite();
                    connection.Close();
                    connection = null;
                }
                else
                {
                    writer.Write(guid.ToByteArray());

                    var headerStream = TransportHeaderWrapper.Serialize(headers);
                    writer.Write((int)headerStream.Length);
                    writer.Write(headerStream.GetBuffer(), 0, (int)headerStream.Length);

                    writer.Write((int)message.Length);
                    MemoryStream ms = message as MemoryStream;
                    if (ms == null)
                    {
                        byte[] msgBuffer = new byte[message.Length];
                        message.Read(msgBuffer, 0, (int)message.Length);
                        writer.Write(msgBuffer, 0, (int)message.Length);
                    }
                    else
                    {
                        writer.Write(ms.GetBuffer(), 0, (int)message.Length);
                    }

                    writer.Flush();
                }
            }
            catch (ObjectDisposedException)
            {
                // Socket may be closed meanwhile. Connection isn't working anymore, so close it.
                connection.ReleaseWrite();
                connection.Close();
                connection = null;
            }
            catch (IOException)
            {
                // Unexpected connection loss. Connection isn't working anymore, so close it.
                connection.ReleaseWrite();
                connection.Close();
                connection = null;
            }
            catch (SocketException)
            {
                // Unexpected connection loss. Connection isn't working anymore, so close it.
                connection.ReleaseWrite();
                connection.Close();
                connection = null;
            }
            catch (RemotingException)
            {
                // Unexpected connection loss. Connection isn't working anymore, so close it.
                connection.ReleaseWrite();
                connection.Close();
                connection = null;
            }
            finally
            {
                if (connection != null)
                {
                    connection.ReleaseWrite();
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Receives a message over a specified Duplex Channel Connection.
        /// </summary>
        /// <param name="connection">Duplex Channel Connection</param>
        /// <param name="ar">Result (for Async pattern)</param>
        /// <returns>Received message</returns>
        public static Message EndReceive(out Connection connection, IAsyncResult ar)
        {
            AsyncResult myAr = (AsyncResult)ar;

            connection = myAr.Connection;
            try
            {
                connection.LockRead();
                if (connection.Socket == null)
                {
                    throw new MessageException("Connection closed.", null, connection);
                }

                int bytesRead = connection.Socket.EndReceive(myAr.InternalAsyncResult);
                if (bytesRead == 16)
                {
                    Message retVal = new Message();
                    retVal.Guid = new Guid(myAr.Buffer);
                    BinaryReader reader = connection.Reader;

                    int          headerLength = reader.ReadInt32();
                    MemoryStream headerStream = new MemoryStream(reader.ReadBytes(headerLength));
                    if (headerStream.Length != headerLength)
                    {
                        throw new Exception("Not enough headers read...");
                    }
                    retVal.Headers = TransportHeaderWrapper.Deserialize(headerStream);

                    int bodyLength = reader.ReadInt32();

                    if (bodyLength > 0)
                    {
                        retVal.messageBodyBytes = reader.ReadBytes(bodyLength);
                        if (retVal.messageBodyBytes.Length != bodyLength)
                        {
                            throw new Exception("Not enough body read...");
                        }

                        System.Diagnostics.Debug.Assert(retVal.MessageBody.CanRead);
                    }

                    Message.BeginReceive(connection, myAr.Callback, myAr.AsyncState);

                    return(retVal);
                }
                else if (bytesRead == 0)
                {
                    throw new MessageException("Connection closed.", null, connection);
                }
                else
                {
                    throw new MessageException("Insufficient data received", null, connection);
                }
            }
            catch (Exception e)
            {
                throw new MessageException("Error receiving message", e, connection);
            }
            finally
            {
                connection.ReleaseRead();
            }
        }