private void OnUdpReceive(IAsyncResult ar) { try { var cbRecv = udpSock.EndReceiveFrom(ar, ref udpRemoteEP); var remoteEP = (IPEndPoint)udpRemoteEP; var prefix = PadPrefix(string.Format("UDP[{0}:{1}]:", remoteEP.Address, remoteEP.Port)); lock (syncLock) { Debug.WriteLine(string.Format("{0} Echoing [{1}] bytes", prefix, cbRecv)); } var udpSendBuf = Helper.Extract(udpRecvBuf, 0, cbRecv); udpSock.BeginSendTo(udpSendBuf, 0, cbRecv, SocketFlags.None, remoteEP, ar2 => { try { udpSock.EndSendTo(ar2); } catch (SocketClosedException) { return; } catch { // Ignore } }, null); if (UdpReceived != null) { UdpReceived(this, new NetReflectorEventArgs() { Endpoint = remoteEP, Data = udpSendBuf }); } udpSock.BeginReceiveFrom(udpRecvBuf, 0, udpRecvBuf.Length, SocketFlags.None, ref udpRemoteEP, onUdpReceive, null); } catch (SocketClosedException) { return; } catch (Exception e) { lock (syncLock) { Debug.WriteLine(string.Format("*** {0}: {1}", e.GetType().Name, e.Message)); } } }
/// <summary> /// Handles message packet send completions on the socket. /// </summary> /// <param name="ar">The async result.</param> private void OnSend(IAsyncResult ar) { ChannelEP toEP; int cb; int cbMsg; using (TimedLock.Lock(router.SyncRoot)) { if (!isOpen || sendMsg == null) { return; } Assertion.Test(sendMsg != null); sendMsg = null; try { cb = sock.EndSendTo(ar); Assertion.Test(cb == cbSend); if (sendQueue.Count > 0) { sendMsg = sendQueue.Dequeue(); toEP = sendMsg._ToEP.ChannelEP; sendMsg._SetFromChannel(localEP); cbMsg = Msg.Save(new EnhancedMemoryStream(msgBuf), sendMsg); sendBuf = router.EncryptFrame(msgBuf, cbMsg); cbSend = sendBuf.Length; Assertion.Validate(cbSend <= TcpConst.MTU, "Message larger than UDP MTU."); sock.BeginSendTo(sendBuf, 0, cbSend, SocketFlags.None, router.NormalizeEP(toEP.NetEP), onSend, null); } } catch { } } }
/// <summary> /// Completes the asynchronous transmission of bytes to the remote side of the connection. /// </summary> /// <param name="ar">The <see cref="IAsyncResult" /> instance returned by the call to <see cref="BeginSend" /> that initiated the transmission.</param> /// <exception cref="SocketException">Thrown if the transmission failed.</exception> /// <exception cref="SocketClosedException">Thrown if the socket has been closed.</exception> /// <remarks> /// <note> /// All successful calls to <see cref="BeginSend" /> must eventually be followed by a call to <see cref="EndSend" />. /// </note> /// </remarks> public void EndSend(IAsyncResult ar) { lock (syncLock) { if (isTcp) { try { sock.EndSend(ar); } finally { tcpSendPending = false; } } else { sock.EndSendTo(ar); } } }