锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 英语翻译 / C#可扩展UDP服务器
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
技术分类
讨论组翻译
UDP掉线重连
异步线程编程和C#UDP服务器大并发模式
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。”需要全文内容也请联系孙老师。

C#可扩展UDP服务器

Introduction 介绍

This article is about a scalable UDP socket server program. This program uses Async Socket methods to support communication with multiple clients. The server is designed in a way that it will isolate receive and send functionality. In this program there is also provision to process your data in individual threads. In any case the server will not stop listening. I have built the skeleton that will provide only the architecture where you can use your business logic for development.

这篇文章是关于一个可扩展的UDP套接字服务器程序。 这个程序使用异步套接字的方法支持与多个客户端通信。 将服务器设计成接收和发送分离功能的方式。 在这个程序中也有规定在单独的线程来处理您的数据。 在任何情况下,服务器不会停止监听。 我已经建立了框架,框架会提供体系结构的发展,您可以为您的业务逻辑进行进一步开发。

Note:- This is a pattern using you can implement the more scalable UDP Server. In case you need more assistance please do write in comments section.

注意:此是可实用模式——是一个可扩展UDP服务器的模式。 如果你需要更多的帮助请写在评论部分。

Background 背景

Our client has real time devices fixed on properties for security. This device is capable of intruder detection and fire smoke detection. There are nearly 5000 devices present all over the country. The device contains a SIM card for the communication. It uses GPRS via the UDP communication protocol. These devices needs a communication rooter which provides understandable information for third party systems.

我们的客户有固定在安全的位置内的实时设备。 这个设备能进行入侵者检测和火灾烟雾检测。 目前有近5000设备遍布全国。 通信设备包含一个SIM卡。 它使用GPRS通过UDP通信协议。 这些设备需要一个通信路由,进而为第三方提供可以理解的信息。

My requirement was to integrate my application with these devices. Due to the high number of clients I needed to develop a server which could manage communication concurrently with multiple devices. The devices need to be communicated to once it starts sending messages. The device starts communication only under a condition: if any of the sensors is activated and triggers the device.

我的要求是将应用程序与这些设备集成。 由于大量的客户我需要开发一个服务器可以同时与多个设备管理沟通。 这些设备一旦它开始发送消息就需要通信。 设备开始通信的条件是:如果任何传感器被激活并触发装置。

Once the device gets triggered in any of the events, devices start sending signals to the server. The server’s responsibility is to respond to these requests and gather data from the device .Then assemble that information and produce the required output.

一旦设备被事件触发,设备开始向服务器发送信号。 服务器的责任是应对这些请求和收集设备的数据。 然后组装信息并产生所需的输出。

To develop this type of application, performance is very critical. The reason for criticality is that all communication to the server is on only one port. We have to manage each and every byte very carefully so it can serve as many devices as possible at a time. The pick time of device calling is morning 8 to 9. Each device has an individual IP and port which communicates on only one port of the server.

开发这种类型的应用程序,性能非常关键。 关键原因是,所有通信在服务器端只用一个端口。 我们必须非常仔细地管理每一字节,所以可以使用尽可能多的设备。 设备要求的选择时间早上8 - 9。 每个设备都有一个单独的IP和端口,它和服务器端唯一端口通信。

Process过程

To develop this application my starting requirement was to establish communication between devices and the server. This is not a difficult problem, I just need to configure the server with an open IP to communicate with the device. The data retrieved from the device is very critical and requires a CRC check. We need to maintain data information in the trace log for each device.

为了开发这个应用程序,我开始的要求是建立设备和服务器之间的通信。 这不是一个困难的问题,我只需要配置服务器以开放IP与设备进行通信。 从设备获取的数据是非常重要的,需要一个CRC检查。 我们需要为每个设备维护数据信息,这通过跟踪日志完成。

With this requirement my first thought was how many concurrent devices we can support. I did research on the communication mode. First I used the Winsock control. The reason for using Winsock is that I was able to send a response to the device. The problem with Winsock is that it is a very heavy object and in the case of a time out, the connection gets disconnected and Winsock sits idle and will not respond to the device. To resolve this problem I found out that I can dispose Winsock and then recreate it. That works but again the time constraint is there.

这个要求我的第一想法是我们可以支持多少并发设备。 我对通信模式做了研究。 首先,我使用Winsock控件。 使用Winsock的原因是,我可以向设备发送一个响应。 Winsock的问题是,在超时的情况下,负荷大,连接断开时会和Winsock处于空闲时,不对设备响应。 要解决这个问题,我发现我可以释放Winsock然后重新创建它,这个方法可行,但是时间有约束。

Then I did some research on the System.Net.Sockets.Socket class. Socket works fine with the device. The good news is Socket supports async communication. One of the advantages about UDP is that it never blocks sending and saves us multiple ports for communication on the server. The socket BeginRecieve() and BeginSendTo() methods are used to manage async calls with different devices.

然后我在System.Net.Sockets.Socket做了一些研究。 套接字与设备工作正常。 好消息是套接字支持异步通信。 UDP的优点之一在于它从未对发送和接收阻塞,支持了我们服务器上的多个端口进行通信。 套接字BeginRecieve()和BeginSendTo()方法用于管理异步调用。

The calls are multiple with the same device because of the data we need to get in multiple chunks. Multiple devices are calling at the same time so we need to keep track of each and every request and reply on the correct device. In case data does not arrive in the defined timeline we need to implement a retry strategy. I used four components in this project.

因为我们需要在多个块中获取数据,所以对同一设备要调用多次。 同时调用多个设备,所以我们需要跟踪每个请求和应答到正确的设备上。 如果数据在定义的时间表前没到达,我们需要实现一个重试策略。 在这个项目里我用四个组件。

GUI will display the on-going process events happening in the application. GUI将显示实时处理事件数据。

The Data Collector class holds data for processing. 数据收集器容纳要处理的数据。

Data process class processes data. 数据处理类处理数据。

Utility functions. 工具函数。

This approach gives me isolation of send receive information and increases response time for the server. 这种方法让我隔离了发送和接收信息,增加服务器响应时间。

Environment Diagram 环境图

The devices communicate via a SIM card to our Session Manager. Once the data is received into the session manager the data is passed to the processing unit. The processing unit contains the data collector and data process modules which has the functionality of handling the data. The session manager is an intelligent unit which is able to manage the traffic of incoming and outgoing data.

通过SIM卡实现的设备通信进入到会话管理器。 一次会话管理器接收到的数据传递给处理单元。 包含数据收集器的处理单元和数据处理模块处理数据。 会话管理器是一种智能单元能够管理通信的传入和传出的数据。

Using the code 使用的代码

The project is divided into four parts.

项目分为四个部分。

UDP.Server

UDP.Server.Utils

UDP.ServerComponents

UDP.ServerCore

Here are the details: 这里有细节:

UDP.Server: This is the starting point of the application. The work of the UDP.Server library is just a part of the View, the traffic, and traffic related events.

UDP 服务器:这是应用程序的起点。 UDP.Server库的工作只是视图、通信和通信事件的一部分。

UDP.ServerCore: This is the main core of the project. The functionality listed below should be present in this module: UDP. ServerCore:这是最主要的核心项目。 下面列出的功能出现在这个模块

Manage send receive data packets of UDP.管理发送接收UDP数据包。

Act as a router for packets to correct data collector container. 作为数据包的路由器来纠正数据收集器的容器。

Once data is collected pass it to the proper process module. 一旦数据被收集通过适当的流程模块。

Clean up the data object once the data is processed. UI.清理一旦数据被处理的数据对象。

Send notification to the server UI 向服务器发送通知UI

UDP.ServerComponents: Secure pass components contain the structure of the data which you need to process. Like an entity class you can create structure, class, or enumeration in this class. In these components there should not be any business logic present. They should only contain the structure. For example, email structure. If you want to send email, create an email structure class. Create an instance of the class and use it wherever you need.

UDPServerComponents:安全传送组件包含你需要处理的数据结构。 它像一个实体类,可以类内创建结构、类、枚举。 在这些组件里不应该有任何业务逻辑。 他们应该只包含结构。 例如,电子邮件的结构。 如果你想发送电子邮件,创建电子邮件结构类。 创建类的实例,并使用它。

UDP.Server.Utils: As per the name I have used this project for all utilities. For FTP connectivity, CRC calculation, and other common functionality I am putting in this project. UDP.Server。 UDP.Server.Utils:按照名字来看,是这个项目的所有工具。对于FTP连接,CRC计算等常见功能,我都放在了 UDP.Server这个项目里。

In this project you will only get the skeleton of the project you need to implement your code as per your requirements. 在这个项目中你只会得到项目需要实现的框架代码按您的要求。
The class SessionManager is the core of the program. SessionManager’s responsibilities are: 类 SessionManager 是这个程序的核心。 SessionManager 的职责是

Start and stop the server.启动和停止服务器。

Receive and send data on UDP.接收和发送UDP数据。

Start processing thread to process data.开始处理线程来处理数据。

Determines data is passed to the correct data collector.确定数据传递到正确的数据收集器。

The class SessionManager is used to manage communication related stuff. The Socket gets initialized when the SessionManagers object is instantiated.类 SessionManager 是用于管理通信相关的东西,套接字被初始化时, SessionManagers 对象被实例化

private Socket _UdpSocket;
     /// <summary>
     /// Initialize socket 
     /// </summary>
     private void InitializeUdpSocket()
     { 
     _UdpSocket = new Socket(AddressFamily.InterNetwork,
     SocketType.Dgram, ProtocolType.Udp);
     }

Below code is for starting the listener. This function starts receiving UDP traffic. UpdateUI is the callback method which will notify the GUI what data we have received.
下面的代码是启动侦听器。 这个函数从接收UDP流量开始。 UpdateUI 是回调方法,将通知GUI我们已收到的数据。

public delegate void UpdateUIDelegate(object value);
     public event UpdateUIDelegate UpdateUI;
     /// <summary>
     /// Start listener
     /// </summary>
     public void StartListener()
     { 
     //Assign the any IP of the machine and listen on port number 52200
     _ReceiveByteData = new byte[1072];
     _UdpSocket.Bind(new IPEndPoint(IPAddress.Any, Int32.Parse(
     SPConfigVal.GetConfigValue(SecurePassConstants.ServerPort))));
     EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
     //Start receiving data
    _UdpSocket.BeginReceiveFrom(_ReceiveByteData, 0, _ReceiveByteData.Length,
     SocketFlags.None, ref newClientEP, DoReceiveFrom, _UdpSocket);
     if (UpdateUI != null)
     {
     UpdateUI(CommonFunctions.GetDateTime() + " Server Stated....");
     }
     }

The DoReceivedForm method is used as async and receives traffic from multiple Devices. Once data is received it transfers data to the collection container. Once data is collected the class returns data for the next request and sends the request as soon as possible. The reason behind this fast process is we need to keep the server ready for new incoming requests.

的 DoReceivedForm 方法用作异步和接收来自多个设备的流量。 一旦接收到数据传输数据的收集容器中。 一旦数据被收集类返回数据为下一个请求并尽快发送请求。 背后的原因这快过程是我们需要保持服务器准备好新传入的请求。

  /// <summary>
     /// socket call back function to receive message from clients
     /// </summary>
     /// <param name="ar"></param>
     private void DoReceiveFrom(IAsyncResult ar)
     {
     try
     {
     Socket recvSock = (Socket)ar.AsyncState;
     EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
     int msgLen = recvSock.EndReceiveFrom(ar, ref clientEP);
     byte[] objbuffer = new byte[msgLen];
     Array.Copy(_ReceiveByteData, objbuffer, msgLen);
     _ReceiveByteData = null;
     //notification of the data on UI
     if (UpdateUI != null)
     {
     UpdateUI(objbuffer);
     }
     _SendByteData = ProcessDeviceData(objbuffer, clientEP);
     SendData(clientEP, _SendByteData);
     }

The request accepted by the device is a 16 byte header. It contains instructions which my application needs. The processDeviceData function returns the request for the next information.

请求接受设备是一个16字节。 它包含我的应用程序的需求指令, processDeviceData 函数返回请求的下一个信息

Components of the application ISession is the data collector root class. IsessionStatusCall and IsessionVideoWakeup are the sub components for the StatusCall and Videowakeup calls. IDeviceDataHandler is a root for the data process class. IStatusChangeDeviceDataHandler, IVideoWakeupDeviceDataHandler are sub interface for video and status. If you look at the code you will find the use of these classes. Using these strategy patterns, we can achieve device traffic communication.

应用程序的组件 ISession 数据收集器。 IsessionStatusCall 和 IsessionVideoWakeup是 StatusCall 和 Videowakeup 的子组件的调用。 IDeviceDataHandler 数据处理类是一个根。 IStatusChangeDeviceDataHandler , IVideoWakeupDeviceDataHandler 子接口的视频和地位。 如果你看看你会发现使用这些策略模式,我们可以实现交通通信设备。

  interface ISession
     interface ISessionStatusCall : ISession
     interface ISessionVideoWakeup:ISession
     interface IStatusChangeDeviceDataHandler : IDeviceDataHandler
     interface IVideoWakeupDeviceDataHandler : IDeviceDataHandler

The Socket.IOControl Property plays very vital role in performance. Socket.IOControl 财产性能中扮演十分重要的角色。

ICMP unreachable error occurs when a router receives a datagram that requires fragmentation, but the “don't fragment” (DF) flag is turned on in the IP header. This error can be used by a program that needs to determine the smallest MTU in the path to a destination-called the path MTU discovery mechanism

ICMP不可到达错误发生在,一个路由器收到一个数据报,需要分段,但IP报头“不要片段”(DF)标志为真。 这个错误可以用于一个程序,来确定路径上最小的MTU,这个路径到达目的呼叫路径MTU发现机制。

Below is the code to avoid this problem.下面的代码可以避免这个问题。

public const int SIO_UDP_CONNRESET = -1744830452;

Then set the low level io control to ignore these messages: 然后设置低水平io控制忽略这些消息:

  var client = new UdpClient(endpoint);
     client.Client.IOControl(IOControlCode)SIO_UDP_CONNRESET,
     new byte[] {0, 0, 0, 0 },null);

Points of Interest 兴趣点

While writing this code I learnt that you can write a UDP server which is capable of handling multiple requests on one port. The benefit of using UDP is that it is state less so there is no problem of managing ack info. The data trace log functionality is also used for writing the received data after processing. The fun thing about UDP is some times you need to ask data twice from the Device and UDP will give you two data packets: one which we asked previously and one which you asked after that.

在写这段代码时,我知道,您可以编写一个UDP服务器能够处理多个请求在一个端口。 使用UDP的好处是,它区块少所以没有应答信息管理的问题。 数据跟踪日志功能也可以用于写作后接收的数据处理。 UDP是好玩的,有时你需要从设备向数据和UDP问两次,会给你两个数据包:其中一个我们以前问和一个你之后问的。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内