Пример #1
0
            public SendAsyncResult(UdpOutputChannel channel, Message message, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.channel = channel;

                //obtain the transaction propagation token from the TransactionFlowProperty on the message
                byte[] txPropToken = TransactionFlowProperty.Get(message);

                this.messageBuffer = channel.EncodeMessage(message);

                txmsgBuffer = TransactionMessageBuffer.WriteTransactionMessageBuffer(txPropToken, messageBuffer);
                if ((long)txmsgBuffer.Length > channel.Factory.MaxPacketSize)
                {
                    throw new CommunicationException("The output packet size is greater than the maximum size supported.");
                }

                try
                {
                    IAsyncResult result = null;
                    try
                    {
                        result = channel.socket.BeginSendTo(txmsgBuffer, 0, txmsgBuffer.Length,
                                                            SocketFlags.None, channel.remoteEndPoint, new AsyncCallback(OnSend), this);
                    }
                    catch (SocketException socketException)
                    {
                        throw UdpChannelHelpers.ConvertTransferException(socketException);
                    }

                    if (!result.CompletedSynchronously)
                    {
                        return;
                    }

                    CompleteSend(result, true);
                }
                catch
                {
                    CleanupBuffer();
                    throw;
                }
            }
Пример #2
0
        public void Send(Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            base.ThrowIfDisposedOrNotOpen();

            //obtain the transaction propagation token from the TransactionFlowProperty on the message
            byte[] txPropToken = TransactionFlowProperty.Get(message);

            ArraySegment <byte> messageBuffer = EncodeMessage(message);

            byte[] txmsgBuffer = TransactionMessageBuffer.WriteTransactionMessageBuffer(txPropToken, messageBuffer);
            if ((long)txmsgBuffer.Length > this.Factory.MaxPacketSize)
            {
                throw new CommunicationException("The output packet size is greater than the maximum size supported.");
            }

            try
            {
                int bytesSent = this.socket.SendTo(txmsgBuffer, 0, txmsgBuffer.Length,
                                                   SocketFlags.None, this.remoteEndPoint);

                if (bytesSent != txmsgBuffer.Length)
                {
                    throw new CommunicationException(string.Format(CultureInfo.CurrentCulture,
                                                                   "A Udp error occurred sending a message to {0}.", this.remoteEndPoint));
                }
            }
            catch (SocketException socketException)
            {
                throw UdpChannelHelpers.ConvertTransferException(socketException);
            }
            finally
            {
                // we need to make sure buffers are always returned to the BufferManager
                parent.BufferManager.ReturnBuffer(messageBuffer.Array);
            }
        }
        Message EndReceive(Socket listenSocket, IAsyncResult result)
        {
            // if we've started the shutdown process, then we've disposed
            // the socket and calls to socket.EndReceive will throw
            if (base.State != CommunicationState.Opened)
            {
                return(null);
            }

            byte[] buffer = ((SocketReceiveState)result.AsyncState).Buffer;

            Message message = null;

            try
            {
                int count = 0;

                lock (ThisLock)
                {
                    // if we've started the shutdown process, socket is disposed
                    // and calls to socket.EndReceive will throw
                    if (base.State == CommunicationState.Opened)
                    {
                        EndPoint dummy = CreateDummyEndPoint(listenSocket);
                        count = listenSocket.EndReceiveFrom(result, ref dummy);
                    }
                }

                if (count > 0)
                {
                    ArraySegment <byte> msg;
                    Transaction         transaction;

                    // read the transaction and message
                    TransactionMessageBuffer.ReadTransactionMessageBuffer(buffer, count, out transaction, out msg);

                    try
                    {
                        message = MessageEncoderFactory.Encoder.ReadMessage(msg, bufferManager);
                    }
                    catch (XmlException xmlException)
                    {
                        throw new ProtocolException(
                                  "There is a problem with the XML that was received from the network. See inner exception for more details.",
                                  xmlException);
                    }

                    if (transaction != null)
                    {
                        // This is where we set the transaction on the message in order to be picked up by
                        // the dispatcher, and used to call the service operation. We use the
                        // System.ServiceModel.Channels.TransactionMessageProperty provided by the WCF framework.
                        TransactionMessageProperty.Set(transaction, message);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Error in completing the async receive via EndReceiveFrom method.");
                Debug.WriteLine(e.ToString());
            }
            finally
            {
                if (message == null)
                {
                    this.bufferManager.ReturnBuffer(buffer);
                    buffer = null;
                }
            }

            return(message);
        }