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; } }
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); }