123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- //------------------------------------------------------------------------------
- // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
- // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
- // CSDN博客:https://blog.csdn.net/qq_40374647
- // 哔哩哔哩视频:https://space.bilibili.com/94253567
- // Gitee源代码仓库:https://gitee.com/RRQM_Home
- // Github源代码仓库:https://github.com/RRQM
- // API首页:https://www.yuque.com/rrqm/touchsocket/index
- // 交流QQ群:234762506
- // 感谢您的下载和使用
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Net.Sockets;
- using System.Runtime.InteropServices;
- using System.Threading;
- using System.Threading.Tasks;
- using TouchSocket.Core;
- using TouchSocket.Resources;
- namespace TouchSocket.Sockets
- {
- /// <summary>
- /// 简单UDP会话。
- /// </summary>
- public class UdpSession : UdpSessionBase
- {
- /// <summary>
- /// 当收到数据时
- /// </summary>
- public UdpReceivedEventHandler Received { get; set; }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="remoteEndPoint"></param>
- /// <param name="byteBlock"></param>
- /// <param name="requestInfo"></param>
- protected override void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo)
- {
- Received?.Invoke(remoteEndPoint, byteBlock, requestInfo);
- }
- }
- /// <summary>
- /// UDP基类服务器。
- /// </summary>
- public class UdpSessionBase : BaseSocket, IUdpSession, IPluginObject
- {
- private readonly ConcurrentList<SocketAsyncEventArgs> m_socketAsyncs;
- private TouchSocketConfig m_config;
- private UdpDataHandlingAdapter m_adapter;
- private NetworkMonitor m_monitor;
- private IPHost m_remoteIPHost;
- private ServerState m_serverState;
- private bool m_usePlugin;
- /// <summary>
- /// 构造函数
- /// </summary>
- public UdpSessionBase()
- {
- m_socketAsyncs = new ConcurrentList<SocketAsyncEventArgs>();
- Protocol = Protocol.UDP;
- Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.ReceiveBufferSize = BufferLength;
- socket.SendBufferSize = BufferLength;
- m_monitor = new NetworkMonitor(null, socket);
- }
- /// <summary>
- /// 处理未经过适配器的数据。返回值表示是否继续向下传递。
- /// </summary>
- public Func<ByteBlock, bool> OnHandleRawBuffer { get; set; }
- /// <summary>
- /// 处理经过适配器后的数据。返回值表示是否继续向下传递。
- /// </summary>
- public Func<ByteBlock, IRequestInfo, bool> OnHandleReceivedData { get; set; }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public bool CanSend => m_serverState == ServerState.Running;
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public virtual bool CanSetDataHandlingAdapter => true;
- /// <summary>
- /// 获取配置
- /// </summary>
- public TouchSocketConfig Config => m_config;
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public IContainer Container => m_config?.Container;
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public DateTime LastReceivedTime { get; private set; }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public DateTime LastSendTime { get; private set; }
- /// <summary>
- /// 数据处理适配器
- /// </summary>
- public UdpDataHandlingAdapter DataHandlingAdapter => m_adapter;
- /// <summary>
- /// 监听器
- /// </summary>
- public NetworkMonitor Monitor => m_monitor;
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public IPluginsManager PluginsManager => m_config?.PluginsManager;
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- public virtual Protocol Protocol { get; set; }
- /// <summary>
- /// 默认远程节点
- /// </summary>
- public IPHost RemoteIPHost => m_remoteIPHost;
- /// <summary>
- /// 服务器名称
- /// </summary>
- public string ServerName => Config?.GetValue(TouchSocketConfigExtension.ServerNameProperty);
- /// <summary>
- /// 获取服务器状态
- /// </summary>
- public ServerState ServerState => m_serverState;
- /// <summary>
- /// 是否已启用插件
- /// </summary>
- public bool UsePlugin => m_usePlugin;
- /// <summary>
- /// 退出组播
- /// </summary>
- /// <param name="multicastAddr"></param>
- public void DropMulticastGroup(IPAddress multicastAddr)
- {
- if (DisposedValue)
- {
- throw new ObjectDisposedException(GetType().FullName);
- }
- if (multicastAddr is null)
- {
- throw new ArgumentNullException(nameof(multicastAddr));
- }
- if (m_monitor.Socket.AddressFamily == AddressFamily.InterNetwork)
- {
- MulticastOption optionValue = new MulticastOption(multicastAddr);
- m_monitor.Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, optionValue);
- }
- else
- {
- IPv6MulticastOption optionValue2 = new IPv6MulticastOption(multicastAddr);
- m_monitor.Socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.DropMembership, optionValue2);
- }
- }
- /// <summary>
- /// 加入组播。
- /// <para>组播地址为 224.0.0.0 ~ 239.255.255.255,其中 224.0.0.0~224.255.255.255 不建议在用户程序中使用,因为它们一般都有特殊用途。</para>
- /// </summary>
- /// <param name="multicastAddr"></param>
- public void JoinMulticastGroup(IPAddress multicastAddr)
- {
- if (multicastAddr is null)
- {
- throw new ArgumentNullException(nameof(multicastAddr));
- }
- if (DisposedValue)
- {
- throw new ObjectDisposedException(GetType().FullName);
- }
- if (m_monitor.Socket.AddressFamily == AddressFamily.InterNetwork)
- {
- MulticastOption optionValue = new MulticastOption(multicastAddr);
- m_monitor.Socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, optionValue);
- }
- else
- {
- IPv6MulticastOption optionValue2 = new IPv6MulticastOption(multicastAddr);
- m_monitor.Socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, optionValue2);
- }
- }
- /// <summary>
- /// 设置数据处理适配器
- /// </summary>
- /// <param name="adapter"></param>
- public virtual void SetDataHandlingAdapter(UdpDataHandlingAdapter adapter)
- {
- if (!CanSetDataHandlingAdapter)
- {
- throw new Exception($"不允许自由调用{nameof(SetDataHandlingAdapter)}进行赋值。");
- }
- SetAdapter(adapter);
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="config"></param>
- /// <returns></returns>
- public IService Setup(TouchSocketConfig config)
- {
- m_config = config;
- if (config.IsUsePlugin)
- {
- PluginsManager.Raise<IConfigPlugin>(nameof(IConfigPlugin.OnLoadingConfig), this, new ConfigEventArgs(config));
- }
- LoadConfig(m_config);
- if (UsePlugin)
- {
- PluginsManager.Raise<IConfigPlugin>(nameof(IConfigPlugin.OnLoadedConfig), this, new ConfigEventArgs(config));
- }
- return this;
- }
- /// <summary>
- /// 通过端口配置
- /// </summary>
- /// <param name="port"></param>
- public IService Setup(int port)
- {
- TouchSocketConfig serverConfig = new TouchSocketConfig();
- serverConfig.SetBindIPHost(new IPHost(port));
- return Setup(serverConfig);
- }
- /// <summary>
- /// 启动服务
- /// </summary>
- public IService Start()
- {
- try
- {
- if (m_serverState == ServerState.Disposed)
- {
- throw new Exception("无法重新利用已释放对象");
- }
- switch (m_serverState)
- {
- case ServerState.None:
- {
- if (m_config.GetValue(TouchSocketConfigExtension.BindIPHostProperty) is IPHost iPHost)
- {
- BeginReceive(iPHost);
- }
- break;
- }
- case ServerState.Running:
- return this;
- case ServerState.Stopped:
- {
- if (m_config.GetValue(TouchSocketConfigExtension.BindIPHostProperty) is IPHost iPHost)
- {
- BeginReceive(iPHost);
- }
- break;
- }
- case ServerState.Disposed:
- {
- throw new Exception("无法再次利用已释放对象");
- }
- }
- m_serverState = ServerState.Running;
- if (UsePlugin)
- {
- PluginsManager.Raise<IServicePlugin>(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, default));
- }
- return this;
- }
- catch (Exception ex)
- {
- m_serverState = ServerState.Exception;
- if (UsePlugin)
- {
- PluginsManager.Raise<IServicePlugin>(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, ex) { Message = ex.Message }) ;
- }
- throw;
- }
-
- }
- /// <summary>
- /// 停止服务器
- /// </summary>
- public IService Stop()
- {
- m_monitor?.Socket.Dispose();
- m_monitor = null;
- m_serverState = ServerState.Stopped;
- foreach (var item in m_socketAsyncs)
- {
- item.SafeDispose();
- }
- m_socketAsyncs.Clear();
- if (UsePlugin)
- {
- PluginsManager.Raise<IServicePlugin>(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, default));
- }
- return this;
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="disposing"></param>
- protected override void Dispose(bool disposing)
- {
- if (!this.DisposedValue)
- {
- if (disposing)
- {
- m_monitor?.Socket.Dispose();
- m_monitor = null;
- m_serverState = ServerState.Disposed;
- foreach (var item in m_socketAsyncs)
- {
- item.SafeDispose();
- }
- m_socketAsyncs.Clear();
- if (UsePlugin)
- {
- PluginsManager.Raise<IServicePlugin>(nameof(IServicePlugin.OnStarted), this, new ServiceStateEventArgs(this.m_serverState, default));
- }
- }
- }
- base.Dispose(disposing);
- }
- /// <summary>
- /// 处理已接收到的数据。
- /// </summary>
- /// <param name="remoteEndPoint"></param>
- /// <param name="byteBlock">以二进制流形式传递</param>
- /// <param name="requestInfo">以解析的数据对象传递</param>
- protected virtual void HandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo)
- {
- }
- /// <summary>
- /// 当即将发送时,如果覆盖父类方法,则不会触发插件。
- /// </summary>
- /// <param name="endPoint"></param>
- /// <param name="buffer">数据缓存区</param>
- /// <param name="offset">偏移</param>
- /// <param name="length">长度</param>
- /// <returns>返回值表示是否允许发送</returns>
- protected virtual bool HandleSendingData(EndPoint endPoint, byte[] buffer, int offset, int length)
- {
- return true;
- }
- /// <summary>
- /// 加载配置
- /// </summary>
- /// <param name="config"></param>
- protected virtual void LoadConfig(TouchSocketConfig config)
- {
- if (config == null)
- {
- throw new Exception("配置文件为空");
- }
- Logger = Container.Resolve<ILog>();
- m_remoteIPHost = config.GetValue(TouchSocketConfigExtension.RemoteIPHostProperty);
- BufferLength = config.GetValue(TouchSocketConfigExtension.BufferLengthProperty);
- m_usePlugin = config.IsUsePlugin;
- if (CanSetDataHandlingAdapter)
- {
- SetDataHandlingAdapter(Config.GetValue(TouchSocketConfigExtension.UdpDataHandlingAdapterProperty).Invoke());
- }
- }
- /// <summary>
- /// 在Socket初始化对象后,Bind之前调用。
- /// 可用于设置Socket参数。
- /// 父类方法可覆盖。
- /// </summary>
- /// <param name="socket"></param>
- protected virtual void PreviewBind(Socket socket)
- {
- }
- /// <summary>
- /// 设置适配器,该方法不会检验<see cref="CanSetDataHandlingAdapter"/>的值。
- /// </summary>
- /// <param name="adapter"></param>
- protected void SetAdapter(UdpDataHandlingAdapter adapter)
- {
- if (adapter is null)
- {
- throw new ArgumentNullException(nameof(adapter));
- }
- if (adapter.m_owner != null)
- {
- throw new Exception("此适配器已被其他终端使用,请重新创建对象。");
- }
- if (Config != null)
- {
- if (Config.GetValue(TouchSocketConfigExtension.MaxPackageSizeProperty) is int v1)
- {
- adapter.MaxPackageSize = v1;
- }
- }
- adapter.m_owner = this;
- adapter.ReceivedCallBack = PrivateHandleReceivedData;
- adapter.SendCallBack = DefaultSend;
- m_adapter = adapter;
- }
- private void BeginReceive(IPHost iPHost)
- {
- int threadCount = Config.GetValue(TouchSocketConfigExtension.ThreadCountProperty);
- threadCount = threadCount < 0 ? 1 : threadCount;
- Socket socket = new Socket(iPHost.AddressFamily, SocketType.Dgram, ProtocolType.Udp)
- {
- ReceiveBufferSize = BufferLength,
- SendBufferSize = BufferLength,
- EnableBroadcast = m_config.GetValue(TouchSocketConfigExtension.EnableBroadcastProperty)
- };
- if (m_config.GetValue(TouchSocketConfigExtension.ReuseAddressProperty))
- {
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- }
- PreviewBind(socket);
- #region Windows下UDP连接被重置错误10054
- #if NET45_OR_GREATER
- const int SIP_UDP_CONNRESET = -1744830452;
- socket.IOControl(SIP_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
- #else
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- const int SIP_UDP_CONNRESET = -1744830452;
- socket.IOControl(SIP_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
- }
- #endif
- #endregion
- socket.Bind(iPHost.EndPoint);
- m_monitor = new NetworkMonitor(iPHost, socket);
- switch (m_config.GetValue(TouchSocketConfigExtension.ReceiveTypeProperty))
- {
- case ReceiveType.Auto:
- {
- #if NET45_OR_GREATER||NET5_0_OR_GREATER
- for (int i = 0; i < threadCount; i++)
- {
- SocketAsyncEventArgs eventArg = new SocketAsyncEventArgs();
- m_socketAsyncs.Add(eventArg);
- eventArg.Completed += IO_Completed;
- ByteBlock byteBlock = new ByteBlock(BufferLength);
- eventArg.UserToken = byteBlock;
- eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity);
- eventArg.RemoteEndPoint = iPHost.EndPoint;
- if (!socket.ReceiveFromAsync(eventArg))
- {
- ProcessReceive(socket, eventArg);
- }
- }
- #else
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- for (int i = 0; i < threadCount; i++)
- {
- SocketAsyncEventArgs eventArg = new SocketAsyncEventArgs();
- m_socketAsyncs.Add(eventArg);
- eventArg.Completed += IO_Completed;
- ByteBlock byteBlock = new ByteBlock(BufferLength);
- eventArg.UserToken = byteBlock;
- eventArg.SetBuffer(byteBlock.Buffer, 0, byteBlock.Capacity);
- eventArg.RemoteEndPoint = iPHost.EndPoint;
- if (!socket.ReceiveFromAsync(eventArg))
- {
- ProcessReceive(socket, eventArg);
- }
- }
- }
- else
- {
- Thread thread = new Thread(Received);
- thread.IsBackground = true;
- thread.Start();
- }
- #endif
- break;
- }
- default:
- throw new Exception("UDP中只支持Auto模式");
- }
- }
- private void Received()
- {
- while (true)
- {
- ByteBlock byteBlock = new ByteBlock();
- try
- {
- EndPoint endPoint = m_monitor.IPHost.EndPoint;
- int r = m_monitor.Socket.ReceiveFrom(byteBlock.Buffer, ref endPoint);
- byteBlock.SetLength(r);
- HandleBuffer(endPoint, byteBlock);
- }
- catch (Exception ex)
- {
- byteBlock.Dispose();
- Logger.Log(LogType.Error, this, ex.Message, ex);
- break;
- }
- }
- }
- private void HandleBuffer(EndPoint endPoint, ByteBlock byteBlock)
- {
- try
- {
- LastReceivedTime = DateTime.Now;
- if (OnHandleRawBuffer?.Invoke(byteBlock) == false)
- {
- return;
- }
- if (DisposedValue)
- {
- return;
- }
- if (m_adapter == null)
- {
- Logger.Error(this, TouchSocketStatus.NullDataAdapter.GetDescription());
- return;
- }
- m_adapter.ReceivedInput(endPoint, byteBlock);
- }
- catch (Exception ex)
- {
- Logger.Log(LogType.Error, this, "在处理数据时发生错误", ex);
- }
- finally
- {
- byteBlock.Dispose();
- }
- }
- private void IO_Completed(object sender, SocketAsyncEventArgs e)
- {
- ProcessReceive((Socket)sender, e);
- }
- private void PrivateHandleReceivedData(EndPoint remoteEndPoint, ByteBlock byteBlock, IRequestInfo requestInfo)
- {
- if (OnHandleReceivedData?.Invoke(byteBlock, requestInfo) == false)
- {
- return;
- }
- if (m_usePlugin)
- {
- UdpReceivedDataEventArgs args = new UdpReceivedDataEventArgs(remoteEndPoint, byteBlock, requestInfo);
- PluginsManager.Raise<IUdpSessionPlugin>(nameof(IUdpSessionPlugin.OnReceivedData), this, args);
- if (args.Handled)
- {
- return;
- }
- }
- HandleReceivedData(remoteEndPoint, byteBlock, requestInfo);
- }
- #region 向默认远程同步发送
- /// <summary>
- /// 向默认终结点发送
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- public virtual void Send(byte[] buffer, int offset, int length)
- {
- if (m_remoteIPHost == null)
- {
- throw new Exception("默认终结点为空");
- }
- Send(m_remoteIPHost.EndPoint, buffer, offset, length);
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="requestInfo"></param>
- /// <exception cref="OverlengthException"></exception>
- /// <exception cref="Exception"></exception>
- public virtual void Send(IRequestInfo requestInfo)
- {
- if (DisposedValue)
- {
- return;
- }
- if (m_adapter == null)
- {
- throw new ArgumentNullException(nameof(DataHandlingAdapter), TouchSocketStatus.NullDataAdapter.GetDescription());
- }
- if (!m_adapter.CanSendRequestInfo)
- {
- throw new NotSupportedException($"当前适配器不支持对象发送。");
- }
- m_adapter.SendInput(requestInfo);
- }
- #endregion 向默认远程同步发送
- #region 向默认远程异步发送
- /// <summary>
- /// IOCP发送
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- /// <exception cref="NotConnectedException"></exception>
- /// <exception cref="OverlengthException"></exception>
- /// <exception cref="Exception"></exception>
- public virtual Task SendAsync(byte[] buffer, int offset, int length)
- {
- return EasyTask.Run(() =>
- {
- Send(buffer, offset, length);
- });
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="requestInfo"></param>
- /// <exception cref="OverlengthException"></exception>
- /// <exception cref="Exception"></exception>
- public virtual Task SendAsync(IRequestInfo requestInfo)
- {
- return EasyTask.Run(() =>
- {
- Send(requestInfo);
- });
- }
- #endregion 向默认远程异步发送
- #region 向设置的远程同步发送
- /// <summary>
- /// 向设置的远程同步发送
- /// </summary>
- /// <param name="remoteEP"></param>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- /// <exception cref="NotConnectedException"></exception>
- /// <exception cref="OverlengthException"></exception>
- /// <exception cref="Exception"></exception>
- public virtual void Send(EndPoint remoteEP, byte[] buffer, int offset, int length)
- {
- m_adapter.SendInput(remoteEP, buffer, offset, length);
- }
- #endregion 向设置的远程同步发送
- #region 向设置的远程异步发送
- /// <summary>
- /// 向设置的远程异步发送
- /// </summary>
- /// <param name="remoteEP"></param>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- /// <exception cref="NotConnectedException"></exception>
- /// <exception cref="OverlengthException"></exception>
- /// <exception cref="Exception"></exception>
- public virtual Task SendAsync(EndPoint remoteEP, byte[] buffer, int offset, int length)
- {
- return EasyTask.Run(() =>
- {
- Send(remoteEP, buffer, offset, length);
- });
- }
- #endregion 向设置的远程异步发送
- private void ProcessReceive(Socket socket, SocketAsyncEventArgs e)
- {
- if (m_serverState == ServerState.Running && e.SocketError == SocketError.Success)
- {
- ByteBlock byteBlock = (ByteBlock)e.UserToken;
- byteBlock.SetLength(e.BytesTransferred);
- HandleBuffer(e.RemoteEndPoint, byteBlock);
- ByteBlock newByteBlock = new ByteBlock(BufferLength);
- e.UserToken = newByteBlock;
- e.SetBuffer(newByteBlock.Buffer, 0, newByteBlock.Buffer.Length);
- try
- {
- if (!socket.ReceiveFromAsync(e))
- {
- ProcessReceive(socket, e);
- }
- }
- catch (System.Exception ex)
- {
- Logger.Log(LogType.Error, this, ex.Message, ex);
- }
- }
- else
- {
- if (e.SocketError != SocketError.Success)
- {
- Logger?.Error(this, $"接收出现错误:{e.SocketError},错误代码:{(int)e.SocketError}");
- e.Dispose();
- }
- }
- }
- #region DefaultSend
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- public void DefaultSend(byte[] buffer, int offset, int length)
- {
- DefaultSend(m_remoteIPHost.EndPoint, buffer, offset, length);
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="endPoint"></param>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- public void DefaultSend(EndPoint endPoint, byte[] buffer, int offset, int length)
- {
- if (HandleSendingData(endPoint, buffer, offset, length))
- {
- if (CanSend)
- {
- m_monitor.Socket.SendTo(buffer, offset, length, SocketFlags.None, endPoint);
- }
- LastSendTime = DateTime.Now;
- }
- }
- #endregion DefaultSend
- #region DefaultSendAsync
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- public Task DefaultSendAsync(byte[] buffer, int offset, int length)
- {
- return EasyTask.Run(() =>
- {
- DefaultSend(buffer, offset, length);
- });
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="endPoint"></param>
- /// <param name="buffer"></param>
- /// <param name="offset"></param>
- /// <param name="length"></param>
- public Task DefaultSendAsync(EndPoint endPoint, byte[] buffer, int offset, int length)
- {
- return EasyTask.Run(() =>
- {
- DefaultSend(buffer, offset, length);
- });
- }
- #endregion DefaultSendAsync
- #region 组合发送
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="transferBytes"></param>
- public void Send(IList<ArraySegment<byte>> transferBytes)
- {
- Send(m_remoteIPHost.EndPoint, transferBytes);
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="endPoint"></param>
- /// <param name="transferBytes"></param>
- public void Send(EndPoint endPoint, IList<ArraySegment<byte>> transferBytes)
- {
- if (m_adapter == null)
- {
- throw new ArgumentNullException(nameof(DataHandlingAdapter), TouchSocketStatus.NullDataAdapter.GetDescription());
- }
- if (!m_adapter.CanSplicingSend)
- {
- throw new NotSupportedException("该适配器不支持拼接发送");
- }
- m_adapter.SendInput(endPoint, transferBytes);
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="transferBytes"></param>
- public Task SendAsync(IList<ArraySegment<byte>> transferBytes)
- {
- return EasyTask.Run(() =>
- {
- Send(transferBytes);
- });
- }
- /// <summary>
- /// <inheritdoc/>
- /// </summary>
- /// <param name="endPoint"></param>
- /// <param name="transferBytes"></param>
- public Task SendAsync(EndPoint endPoint, IList<ArraySegment<byte>> transferBytes)
- {
- return EasyTask.Run(() =>
- {
- Send(endPoint, transferBytes);
- });
- }
- #endregion 组合发送
- }
- }
|