


Articles de la série de programmation réseau C# (6) Socket implémente un serveur UDP synchrone
Cet article présente
Dans .Net, l'espace de noms System.Net.Sockets fournit une implémentation gérée de l'interface Windows Sockets (Winsock) pour les développeurs qui doivent contrôler étroitement l'accès au réseau. Toutes les autres classes d'accès réseau de l'espace de noms System.Net sont construites sur cette implémentation de socket. Les classes TCPClient, TCPListener et UDPClient encapsulent des informations détaillées sur la création de connexions TCP et UDP à Internet. La classe NetworkStream fournit le flux de données de base du réseau ; accès, Socket peut être vu dans de nombreux services Internet courants, tels que Telnet, HTTP, Email, Echo, etc. Bien que ces services aient des définitions différentes des protocoles de communication, leur transmission de base utilise Socket.
En fait, Socket peut être considéré comme un canal de données comme un Stream. Ce canal s'établit entre l'application (client) et le serveur distant. Ensuite, la lecture (réception) et l'écriture (envoi) des données se font toutes deux via ce canal. .
On peut voir qu'après avoir créé un objet Socket côté application ou côté serveur, vous pouvez utiliser la méthode Send/SentTo pour envoyer des données au Socket connecté, ou utiliser la méthode Receiver/ReceiveFrom pour recevoir des données du Socket connecté. Socket ;
Pour la programmation Socket, la classe Socket du .NET Framework est une version de code géré du service socket fourni par l'API Winsock32. Il existe un certain nombre de méthodes fournies pour implémenter la programmation réseau et, dans la plupart des cas, les méthodes de la classe Socket rassemblent simplement les données vers leurs copies Win32 natives et gèrent tous les contrôles de sécurité nécessaires. Si vous êtes familier avec les fonctions de l'API Winsock, il sera très simple d'utiliser la classe Socket pour écrire des programmes réseau. Bien sûr, si vous n'y avez jamais été exposé, ce ne sera pas trop difficile. constatez que l'utilisation de la classe Socket pour développer des applications réseau Windows comporte en réalité des règles à trouver, et elles suivent à peu près les mêmes étapes dans la plupart des cas.
Cette section présente l'utilisation de Socket pour implémenter un serveur UDP synchrone.
Serveur UDP de synchronisation de socket
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.Threading; namespace NetFrame.Net.UDP.Sock.Synchronous { /// <summary> /// Socket 实现同步UDP服务器 /// </summary> public class SocketUDPServer { #region Fields /// <summary> /// 服务器程序允许的最大客户端连接数 /// </summary> private int _maxClient; /// <summary> /// 当前的连接的客户端数 /// </summary> private int _clientCount; /// <summary> /// 服务器使用的同步socket /// </summary> private Socket _serverSock; /// <summary> /// 客户端会话列表 /// </summary> private List<SocketUDPState> _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> /// 监听的端口 /// </summary> public int Port { get; private set; } /// <summary> /// 通信使用的编码 /// </summary> public Encoding Encoding { get; set; } #endregion #region 构造函数 /// <summary> /// 异步Socket UDP服务器 /// </summary> /// <param name="listenPort">监听的端口</param> public SocketUDPServer(int listenPort) : this(IPAddress.Any, listenPort,1024) { } /// <summary> /// 异步Socket UDP服务器 /// </summary> /// <param name="localEP">监听的终结点</param> public SocketUDPServer(IPEndPoint localEP) : this(localEP.Address, localEP.Port,1024) { } /// <summary> /// 异步Socket UDP服务器 /// </summary> /// <param name="localIPAddress">监听的IP地址</param> /// <param name="listenPort">监听的端口</param> /// <param name="maxClient">最大客户端数量</param> public SocketUDPServer(IPAddress localIPAddress, int listenPort, int maxClient) { this.Address = localIPAddress; this.Port = listenPort; this.Encoding = Encoding.Default; _maxClient = maxClient; _clients = new List<SocketUDPState>(); _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)); //启动一个线程监听数据 new Thread(ReceiveData).Start(); } } /// <summary> /// 停止服务器 /// </summary> public void Stop() { if (IsRunning) { IsRunning = false; _serverSock.Close(); //TODO 关闭对所有客户端的连接 CloseAllClient(); } } /// <summary> /// 同步数据接收方法 /// </summary> private void ReceiveData() { int len = -1; EndPoint remote = null; while (true) { try { len = _serverSock.ReceiveFrom(_recvBuffer, ref remote); //if (!_clients.Contains(remote)) //{ // _clients.Add(remote); //} } catch (Exception) { //TODO 异常处理操作 RaiseOtherException(null); } } } /// <summary> /// 同步发送数据 /// </summary> public void Send(string msg, EndPoint clientip) { byte[] data = Encoding.Default.GetBytes(msg); try { _serverSock.SendTo(data, clientip); //数据发送完成事件 RaiseCompletedSend(null); } catch (Exception) { //TODO 异常处理 RaiseOtherException(null); } } #endregion #region 事件 /// <summary> /// 接收到数据事件 /// </summary> public event EventHandler<SocketUDPEventArgs> DataReceived; private void RaiseDataReceived(SocketUDPState state) { if (DataReceived != null) { DataReceived(this, new SocketUDPEventArgs(state)); } } /// <summary> /// 数据发送完毕事件 /// </summary> public event EventHandler<SocketUDPEventArgs> CompletedSend; /// <summary> /// 触发数据发送完毕的事件 /// </summary> /// <param name="state"></param> private void RaiseCompletedSend(SocketUDPState state) { if (CompletedSend != null) { CompletedSend(this, new SocketUDPEventArgs(state)); } } /// <summary> /// 网络错误事件 /// </summary> public event EventHandler<SocketUDPEventArgs> NetError; /// <summary> /// 触发网络错误事件 /// </summary> /// <param name="state"></param> private void RaiseNetError(SocketUDPState state) { if (NetError != null) { NetError(this, new SocketUDPEventArgs(state)); } } /// <summary> /// 异常事件 /// </summary> public event EventHandler<SocketUDPEventArgs> OtherException; /// <summary> /// 触发异常事件 /// </summary> /// <param name="state"></param> private void RaiseOtherException(SocketUDPState state, string descrip) { if (OtherException != null) { OtherException(this, new SocketUDPEventArgs(descrip, state)); } } private void RaiseOtherException(SocketUDPState state) { RaiseOtherException(state, ""); } #endregion #region Close /// <summary> /// 关闭一个与客户端之间的会话 /// </summary> /// <param name="state">需要关闭的客户端会话对象</param> public void Close(SocketUDPState state) { if (state != null) { _clients.Remove(state); _clientCount--; //TODO 触发关闭事件 } } /// <summary> /// 关闭所有的客户端会话,与所有的客户端连接会断开 /// </summary> public void CloseAllClient() { foreach (SocketUDPState 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 } }
Classe d'encapsulation de l'état du client
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; namespace NetFrame.Net.UDP.Sock.Synchronous { public class SocketUDPState { // 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); } }
Classe de paramètres d'événement du serveur
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace NetFrame.Net.UDP.Sock.Synchronous { /// <summary> /// Socket实现同步UDP服务器 /// </summary> public class SocketUDPEventArgs:EventArgs { /// <summary> /// 提示信息 /// </summary> public string _msg; /// <summary> /// 客户端状态封装类 /// </summary> public SocketUDPState _state; /// <summary> /// 是否已经处理过了 /// </summary> public bool IsHandled { get; set; } public SocketUDPEventArgs(string msg) { this._msg = msg; IsHandled = false; } public SocketUDPEventArgs(SocketUDPState state) { this._state = state; IsHandled = false; } public SocketUDPEventArgs(string msg, SocketUDPState state) { this._msg = msg; this._state = state; IsHandled = false; } } }
Ce qui précède est le contenu de Socket pour synchroniser le serveur UDP dans l'article de la série de programmation réseau C# (6). Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'Active Directory avec C#. Nous discutons ici de l'introduction et du fonctionnement d'Active Directory en C# ainsi que de la syntaxe et de l'exemple.

Guide de sérialisation C#. Nous discutons ici de l'introduction, des étapes de l'objet de sérialisation C#, du fonctionnement et de l'exemple respectivement.

Guide du générateur de nombres aléatoires en C#. Nous discutons ici du fonctionnement du générateur de nombres aléatoires, du concept de nombres pseudo-aléatoires et sécurisés.

Guide de la vue Grille de données C#. Nous discutons ici des exemples de la façon dont une vue de grille de données peut être chargée et exportée à partir de la base de données SQL ou d'un fichier Excel.

Guide des modèles en C#. Nous discutons ici de l'introduction et des 3 principaux types de modèles en C# ainsi que de ses exemples et de l'implémentation du code.

Guide des nombres premiers en C#. Nous discutons ici de l'introduction et des exemples de nombres premiers en c# ainsi que de l'implémentation du code.

Guide de Factorial en C#. Nous discutons ici de l'introduction de factorial en c# ainsi que de différents exemples et de l'implémentation du code.

La différence entre le multithreading et l'asynchrone est que le multithreading exécute plusieurs threads en même temps, tandis que les opérations effectuent de manière asynchrone sans bloquer le thread actuel. Le multithreading est utilisé pour les tâches à forte intensité de calcul, tandis que de manière asynchrone est utilisée pour l'interaction utilisateur. L'avantage du multi-threading est d'améliorer les performances informatiques, tandis que l'avantage des asynchrones est de ne pas bloquer les threads d'interface utilisateur. Le choix du multithreading ou asynchrone dépend de la nature de la tâche: les tâches à forte intensité de calcul utilisent le multithreading, les tâches qui interagissent avec les ressources externes et doivent maintenir la réactivité de l'interface utilisateur à utiliser asynchrone.
