//returns true if receive completed synchronously, false otherwise bool StartAsyncReceive(UdpSocket socket) { Fx.Assert(socket != null, "UdpSocketReceiveManager.StartAsyncReceive: Socket should never be null"); bool completedSync = false; ArraySegment <byte> messageBytes = default(ArraySegment <byte>); UdpSocketReceiveState state = null; lock (this.thisLock) { if (!this.IsDisposed && socket.PendingReceiveCount < this.maxPendingReceivesPerSocket) { IAsyncResult result = null; byte[] receiveBuffer = this.receiveBufferPool.Take(); try { state = new UdpSocketReceiveState(socket, receiveBuffer); EndPoint remoteEndpoint = socket.CreateIPAnyEndPoint(); result = socket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, ref remoteEndpoint, onReceiveFrom, state); } catch (Exception e) { if (!Fx.IsFatal(e)) { this.receiveBufferPool.Return(receiveBuffer); } throw; } if (result.CompletedSynchronously) { completedSync = true; messageBytes = EndReceiveFrom(result, state); } } } if (completedSync) { messageBytes = this.CopyMessageIntoBufferManager(messageBytes); //if HandleDataReceived returns false, it means that the max pending message count was hit. //when receiveHandler.HandleDataReceived is called (whether now or later), it will return the buffer to the buffer manager. return(this.receiveHandler.HandleDataReceived(messageBytes, state.RemoteEndPoint, state.Socket.InterfaceIndex, this.onMessageDequeued)); } return(false); }
//call under a lock ArraySegment <byte> EndReceiveFrom(IAsyncResult result, UdpSocketReceiveState state) { try { EndPoint remoteEndpoint = null; ArraySegment <byte> messageBytes = state.Socket.EndReceiveFrom(result, ref remoteEndpoint); state.RemoteEndPoint = remoteEndpoint; Fx.Assert(messageBytes.Array == state.ReceiveBuffer, "Array returned by Socket.EndReceiveFrom must match the array passed in through the UdpSocketReceiveState"); return(messageBytes); } catch (Exception e) { if (!Fx.IsFatal(e)) { this.receiveBufferPool.Return(state.ReceiveBuffer); } throw; } }
void OnReceiveFrom(IAsyncResult result) { if (result.CompletedSynchronously) { return; } UdpSocketReceiveState state = (UdpSocketReceiveState)result.AsyncState; ArraySegment <byte> messageBytes; bool continueReceiving = true; try { lock (this.thisLock) { if (this.IsDisposed) { return; } messageBytes = EndReceiveFrom(result, state); } messageBytes = this.CopyMessageIntoBufferManager(messageBytes); //when receiveHandler.HandleDataReceived is called, it will return the buffer to the buffer manager. continueReceiving = this.receiveHandler.HandleDataReceived(messageBytes, state.RemoteEndPoint, state.Socket.InterfaceIndex, this.onMessageDequeued); } catch (Exception ex) { if (!TryHandleException(ex)) { throw; } } finally { if (!this.IsDisposed && continueReceiving) { ContinueReceiving(state.Socket); } } }
//call under a lock ArraySegment<byte> EndReceiveFrom(IAsyncResult result, UdpSocketReceiveState state) { try { EndPoint remoteEndpoint = null; ArraySegment<byte> messageBytes = state.Socket.EndReceiveFrom(result, ref remoteEndpoint); state.RemoteEndPoint = remoteEndpoint; Fx.Assert(messageBytes.Array == state.ReceiveBuffer, "Array returned by Socket.EndReceiveFrom must match the array passed in through the UdpSocketReceiveState"); return messageBytes; } catch (Exception e) { if (!Fx.IsFatal(e)) { this.receiveBufferPool.Return(state.ReceiveBuffer); } throw; } }
//returns true if receive completed synchronously, false otherwise bool StartAsyncReceive(UdpSocket socket) { Fx.Assert(socket != null, "UdpSocketReceiveManager.StartAsyncReceive: Socket should never be null"); bool completedSync = false; ArraySegment<byte> messageBytes = default(ArraySegment<byte>); UdpSocketReceiveState state = null; lock (this.thisLock) { if (!this.IsDisposed && socket.PendingReceiveCount < this.maxPendingReceivesPerSocket) { IAsyncResult result = null; byte[] receiveBuffer = this.receiveBufferPool.Take(); try { state = new UdpSocketReceiveState(socket, receiveBuffer); EndPoint remoteEndpoint = socket.CreateIPAnyEndPoint(); result = socket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, ref remoteEndpoint, onReceiveFrom, state); } catch (Exception e) { if (!Fx.IsFatal(e)) { this.receiveBufferPool.Return(receiveBuffer); } throw; } if (result.CompletedSynchronously) { completedSync = true; messageBytes = EndReceiveFrom(result, state); } } } if (completedSync) { messageBytes = this.CopyMessageIntoBufferManager(messageBytes); //if HandleDataReceived returns false, it means that the max pending message count was hit. //when receiveHandler.HandleDataReceived is called (whether now or later), it will return the buffer to the buffer manager. return this.receiveHandler.HandleDataReceived(messageBytes, state.RemoteEndPoint, state.Socket.InterfaceIndex, this.onMessageDequeued); } return false; }