page contents

C#网络编程SOCKET实现异步UDPSERVER

本文讲述了C# 中DrawString()方法如何使用!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-08-Alh77RB962e9d0eeb7a23.png本文讲述了C#网络编程SOCKET实现异步UDPSERVER !具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

在.Net中,System.Net.Sockets 命名空间为须要严密控制网络訪问的开发者提供了 Windows Sockets (Winsock) 接口的托管实现。System.Net 命名空间中的全部其它网络訪问类都建立在该套接字Socket实现之上,如TCPClient、TCPListener 和 UDPClient 类封装有关创建到 Internet 的 TCP 和 UDP 连接的具体信息;NetworkStream类则提供用于网络訪问的基础数据流等,常见的很多Internet服务都能够见到Socket的踪影,如Telnet、Http、Email、Echo等,这些服务虽然通讯协议Protocol的定义不同。可是其基础的传输都是採用的Socket。

 事实上,Socket能够象流Stream一样被视为一个数据通道,这个通道架设在应用程序端(client)和远程server端之间,而后,数据的读取(接收)和写入(发送)均针对这个通道来进行。 
可见,在应用程序端或者server端创建了Socket对象之后。就能够使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据。 
针对Socket编程,.NET 框架的 Socket 类是 Winsock32 API 提供的套接字服务的托管代码版本号。当中为实现网络编程提供了大量的方法,大多数情况下,Socket 类方法仅仅是将数据封送到它们的本机 Win32 副本中并处理不论什么必要的安全检查。假设你熟悉Winsock API函数。那么用Socket类编写网络程序会很easy。当然,假设你不曾接触过。也不会太困难,尾随以下的讲解,你会发觉使用Socket类开发windows 网络应用程序原来有规可寻。它们在大多数情况下遵循大致同样的步骤。

本节介绍使用Socket来实现一个高性能的异步UDPserver,实际上UDP是不分客户机和server的,可是我们有的时候和server通讯就是使用UDP来进行的。

Socket异步UDPserver

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace NetFrame.Net.UDP.Sock.Asynchronous
{
    /// <summary>
    /// SOCKET实现异步UDP服务器
    /// </summary>
    public class AsyncSocketUDPServer
    {
        #region Fields
        /// <summary>
        /// 服务器程序同意的最大客户端连接数
        /// </summary>
        private int _maxClient;

        /// <summary>
        /// 当前的连接的客户端数
        /// </summary>
        //private int _clientCount;

        /// <summary>
        /// 服务器使用的同步socket
        /// </summary>
        private Socket _serverSock;

        /// <summary>
        /// 客户端会话列表
        /// </summary>
        //private List<AsyncUDPSocketState> _clients;

        private bool disposed = false;

        /// <summary>
        /// 数据接受缓冲区
        /// </summary>
        private byte[] _recvBuffer;

        #endregion

        #region Properties

        /// <summary>
        /// 服务器是否正在执行
        /// </summary>
        public bool IsRunning { get; private set; }
        /// <summary>
        /// 监听的IP地址
        /// </summary>
        public IPAddress Address { get; private set; }
        /// <summary>
        /// 监听的port
        /// </summary>
        public int Port { get; private set; }
        /// <summary>
        /// 通信使用的编码
        /// </summary>
        public Encoding Encoding { get; set; }

        #endregion

        #region 构造函数

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="listenPort">监听的port</param>
        public AsyncSocketUDPServer(int listenPort)
            : this(IPAddress.Any, listenPort,1024)
        {
        }

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="localEP">监听的终结点</param>
        public AsyncSocketUDPServer(IPEndPoint localEP)
            : this(localEP.Address, localEP.Port,1024)
        {
        }

        /// <summary>
        /// 异步Socket UDP服务器
        /// </summary>
        /// <param name="localIPAddress">监听的IP地址</param>
        /// <param name="listenPort">监听的port</param>
        /// <param name="maxClient">最大客户端数量</param>
        public AsyncSocketUDPServer(IPAddress localIPAddress, int listenPort, int maxClient)
        {
            this.Address = localIPAddress;
            this.Port = listenPort;
            this.Encoding = Encoding.Default;

            _maxClient = maxClient;
            //_clients = new List<AsyncUDPSocketState>();
            _serverSock = new Socket(localIPAddress.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            _recvBuffer=new byte[_serverSock.ReceiveBufferSize];
        }

        #endregion

        #region Method
        /// <summary>
        /// 启动服务器
        /// </summary>
        /// <returns>异步TCP服务器</returns>
        public void Start()
        {
            if (!IsRunning)
            {
                IsRunning = true;
                _serverSock.Bind(new IPEndPoint(this.Address, this.Port));
                //_serverSock.Connect(new IPEndPoint(IPAddress.Any, 0));

                AsyncSocketUDPState so = new AsyncSocketUDPState();
                so.workSocket = _serverSock;

                _serverSock.BeginReceiveFrom(so.buffer, 0, so.buffer.Length, SocketFlags.None,
                    ref so.remote, new AsyncCallback(ReceiveDataAsync), null);


                //EndPoint sender = new IPEndPoint(IPAddress.Any, 0);

                //_serverSock.BeginReceiveFrom(_recvBuffer, 0, _recvBuffer.Length, SocketFlags.None,
                //    ref sender, new AsyncCallback(ReceiveDataAsync), sender);

                //BeginReceive 和 BeginReceiveFrom的差别是什么
                /*_serverSock.BeginReceive(_recvBuffer, 0, _recvBuffer.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveDataAsync), null);*/
            }
        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        public void Stop()
        {
            if (IsRunning)
            {
                IsRunning = false;
                _serverSock.Close();
                //TODO 关闭对全部客户端的连接

            }
        }

        /// <summary>
        /// 接收数据的方法
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveDataAsync(IAsyncResult ar)
        {
            AsyncSocketUDPState so = ar.AsyncState as AsyncSocketUDPState;
            //EndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            int len = -1;
            try
            {
                len = _serverSock.EndReceiveFrom(ar, ref so.remote);

                //len = _serverSock.EndReceiveFrom(ar, ref sender);

                //EndReceiveFrom 和 EndReceive差别
                //len = _serverSock.EndReceive(ar);
                //TODO 处理数据

                //触发数据收到事件
                RaiseDataReceived(so);
            }
            catch (Exception)
            {
                //TODO 处理异常
                RaiseOtherException(so);
            }
            finally
            {
                if (IsRunning && _serverSock != null)
                    _serverSock.BeginReceiveFrom(so.buffer, 0, so.buffer.Length, SocketFlags.None,
                ref so.remote, new AsyncCallback(ReceiveDataAsync), so);
            }
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="remote"></param>
        public void Send(string msg,EndPoint remote)
        {
            byte[] data = Encoding.Default.GetBytes(msg);
            try
            {
                RaisePrepareSend(null);
                _serverSock.BeginSendTo(data, 0, data.Length, SocketFlags.None, remote, new AsyncCallback(SendDataEnd), _serverSock);
            }
            catch (Exception)
            {
                //TODO 异常处理
                RaiseOtherException(null);
            }
        }

        private void SendDataEnd(IAsyncResult ar)
        {
            ((Socket)ar.AsyncState).EndSendTo(ar);
            RaiseCompletedSend(null);
        }

        #endregion

        #region 事件
        /// <summary>
        /// 接收到数据事件
        /// </summary>
        public event EventHandler<AsyncSocketUDPEventArgs> DataReceived;

        private void RaiseDataReceived(AsyncSocketUDPState state)
        {
            if (DataReceived != null)
            {
                DataReceived(this, new AsyncSocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 发送数据前的事件
        /// </summary>
        public event EventHandler<AsyncSocketUDPEventArgs> PrepareSend;

        /// <summary>
        /// 触发发送数据前的事件
        /// </summary>
        /// <param name="state"></param>
        private void RaisePrepareSend(AsyncSocketUDPState state)
        {
            if (PrepareSend != null)
            {
                PrepareSend(this, new AsyncSocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 数据发送完成事件
        /// </summary>
        public event EventHandler<AsyncSocketUDPEventArgs> CompletedSend;

        /// <summary>
        /// 触发数据发送完成的事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseCompletedSend(AsyncSocketUDPState state)
        {
            if (CompletedSend != null)
            {
                CompletedSend(this, new AsyncSocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 网络错误事件
        /// </summary>
        public event EventHandler<AsyncSocketUDPEventArgs> NetError;
        /// <summary>
        /// 触发网络错误事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseNetError(AsyncSocketUDPState state)
        {
            if (NetError != null)
            {
                NetError(this, new AsyncSocketUDPEventArgs(state));
            }
        }

        /// <summary>
        /// 异常事件
        /// </summary>
        public event EventHandler<AsyncSocketUDPEventArgs> OtherException;
        /// <summary>
        /// 触发异常事件
        /// </summary>
        /// <param name="state"></param>
        private void RaiseOtherException(AsyncSocketUDPState state, string descrip)
        {
            if (OtherException != null)
            {
                OtherException(this, new AsyncSocketUDPEventArgs(descrip, state));
            }
        }
        private void RaiseOtherException(AsyncSocketUDPState state)
        {
            RaiseOtherException(state, "");
        }
        #endregion

        #region Close
        /// <summary>
        /// 关闭一个与客户端之间的会话
        /// </summary>
        /// <param name="state">须要关闭的客户端会话对象</param>
        public void Close(AsyncSocketUDPState state)
        {
            if (state != null)
            {
                //_clients.Remove(state);
                //_clientCount--;
                //TODO 触发关闭事件
            }
        }
        /// <summary>
        /// 关闭全部的客户端会话,与全部的客户端连接会断开
        /// </summary>
        public void CloseAllClient()
        {
            //foreach (AsyncUDPSocketState client in _clients)
            //{
            //    Close(client);
            //}
            //_clientCount = 0;
            //_clients.Clear();
        }

        #endregion

        #region 释放
        /// <summary>
        /// Performs application-defined tasks associated with freeing, 
        /// releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release 
        /// both managed and unmanaged resources; <c>false</c> 
        /// to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    try
                    {
                        Stop();
                        if (_serverSock != null)
                        {
                            _serverSock = null;
                        }
                    }
                    catch (SocketException)
                    {
                        //TODO
                        RaiseOtherException(null);
                    }
                }
                disposed = true;
            }
        }
        #endregion
    }
}


会话封装类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace NetFrame.Net.UDP.Sock.Asynchronous
{
    public class AsyncSocketUDPState
    {
        // Client   socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();

        public EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
    }
}

Socket异步UDPserver事件參数类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetFrame.Net.UDP.Sock.Asynchronous
{
    /// <summary>
    /// SOCKET 异步UDP 事件类
    /// </summary>
    public class AsyncSocketUDPEventArgs : EventArgs
    {
        /// <summary>
        /// 提示信息
        /// </summary>
        public string _msg;

        /// <summary>
        /// client状态封装类
        /// </summary>
        public AsyncSocketUDPState _state;

        /// <summary>
        /// 是否已经处理过了
        /// </summary>
        public bool IsHandled { get; set; }

        public AsyncSocketUDPEventArgs(string msg)
        {
            this._msg = msg;
            IsHandled = false;
        }
        public AsyncSocketUDPEventArgs(AsyncSocketUDPState state)
        {
            this._state = state;
            IsHandled = false;
        }
        public AsyncSocketUDPEventArgs(string msg, AsyncSocketUDPState state)
        {
            this._msg = msg;
            this._state = state;
            IsHandled = false;
        }
    }
}

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2022-08-03 09:36
  • 阅读 ( 401 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1312 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章