局域网内数据采集总结(二)

数据处理中心并不知道各个数据产生终端的具体位置(IP地址区分),因此和特定终端在建立命令通道和数据流通道之前必须事先捕获其IP。

基于UDP的特性,终端的发现使用UDP协议实现。

(1)UDP特性:

UDP是一个无连接协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。UDP不存在粘包的现象,它是有报文边界的,接收方调用一次接收保证只会收到一个udp包(待接收的包长度如果超过你提供的缓冲区长度,那么底层会简单的丢弃这个包,导致你收不到数据,理论上包含报头在内的数据报的最大长度为65535字节)。
(2)终端发现机制:
使用UDP的广播特性,每个数据终端做子网广播。数据处理中心在特定端口接收广播,获取终端IP并使用。因为数据处理中心只是实现接入端的发现,因此无需回复响应报文给检测到的数据终端。
(3)设计概要:
因为UDP传输是对等的,不存在服务端和客户端的区别,但是作为终端发现类库的实现,应给类库的使用者提供合理,人性的调用接口(构造函数,开始监听,停止监听,释放资源,注册事件)。
类库命名为UdpServer,包含监听类,事件参数类,事件产生类,方法调用类。其中事件参数类中包含2个属性,一个是Message(string),一个是EndPoint( System.Net.EndPoint)。数据终端广播来的自身信息,比如IP,名称,固件版本等传递给Message。EndPoint包含IP和Port。因终端广播的数据包含其自身IP,其实EndPoint并没有使用。
(4)类关系图如下:



(5)异步接收代码

BaseServer.cs中:

internal void Start()
{
if (this._serverState == 0)
{
this._serverState = 1;
this._listenThread = new Thread(new ThreadStart(this.OnListen));
this._listenThread.IsBackground = true;
this._listenThread.Start();
}
}

MyUdpListener.cs中:

private void OnBeginReceiveFrom(IAsyncResult ar)
{
try
{
ReceiveState asyncState
= ar.AsyncState as ReceiveState;
EndPoint endPoint
= new IPEndPoint(IPAddress.Any, 0);
if ((this.mUdpClient != null) && (this.mUdpClient.Client != null))
{
this.mUdpClient.Client.EndReceiveFrom(ar, ref endPoint);
string message = Encoding.UTF8.GetString(asyncState.Buffer).Replace("\0", "");
base.RaiseEvent(new NewMessage(endPoint, message));
asyncState.SetEvent();
}
}
catch
{
}
}

protected internal override void OnProcessRequest()
{
EndPoint remoteEP
= new IPEndPoint(IPAddress.Any, 0);
AutoResetEvent evt
= new AutoResetEvent(false);
ReceiveState state
= new ReceiveState(evt);
try
{
this.mUdpClient.Client.BeginReceiveFrom(state.Buffer, 0, 0x400, SocketFlags.None, ref remoteEP, new AsyncCallback(this.OnBeginReceiveFrom), state);
evt.WaitOne();
}
catch
{
}
Thread.Sleep(
10);
}

posted @ 2011-06-02 22:11  Lesterwang  阅读(905)  评论(2编辑  收藏  举报