前面几篇日志中,介绍了有关UDP的数据收发方法,在UDP技巧3中,发送数据已经使用了UdpClient,但由于接收时,需要非阻塞操作,所以使用了socket方法。随着项目的进展,进一步发现,直接使用UdpClient也可以完成UDP的非阻塞操作,而且程序异常简单,本文就将详细介绍这种UDP数据收发方法。
1、为了使用UdpClient,我们首先需要引入以下命名空间。
Imports System.Net Imports System.Net.Sockets Imports System.Threading
2、在主窗体中,声明全局变量,以方便各方法函数调用。在声明时,可直接指明本地端口号,例如下面程序我们声明了一个UdpClient对象,并指明自身端口号为929。
Dim udp As New UdpClient(929)
3、在窗体的加载函数中,启用线程,用于接收UDP数据。如下程序,指明线程的处理函数是thread_udp_receive,并将SocketIsValid变量设置为True,用于告知线程不退出,当窗体结束的时候将SocketIsValid变量设置为False,以结束线程。
SocketIsValid = True Dim thread As Thread = New Thread(New ThreadStart(AddressOf thread_udp_receive)) thread.Start()
4、接下来是结束线程处理函数,首先函数从数据库中取得远程IP地址和端口号存于ip_end_point中,然后声明data数组用于接收数据。接下来进入while循环,先判断Available属性,如果该属性为1就表明缓存中有数据,用Receive方法取出,否则就延时100ms,这样就实现了非阻塞操作。
Private Sub thread_udp_receive() Dim ip_end_point As IPEndPoint Dim strsql As String Dim rst As ADODB.Recordset strsql = "select * from configuration_net where MINGCHENG = 'configuration_net'" rst = myADO.OpenRecordset(strsql) If Not rst.EOF Then ip_end_point = New IPEndPoint(IPAddress.Parse(rst.Fields("LocalIP_A").Value & "." & rst.Fields("LocalIP_B").Value & "." & rst.Fields("LocalIP_C").Value & "." & rst.Fields("LocalIP_D").Value),929) Else ip_end_point = New IPEndPoint(IPAddress.Parse("192.168.0.1"),1000) End If rst.Close() Dim data(1024) As Byte While True If udp.Available > 0 Then data = udp.Receive(ip_end_point) sub_udp_receive(data,data.Length) Else common.Delay(100) End If If SocketIsValid = False Then udp.Close() Exit While End If End While End Sub
5、下面是发送函数,这个在应用技巧4中已经介绍过,其基本思路是从数据库中获得远程主机IP地址和端口号,然后准备发送数据,并计算效验和,调用udp.Send函数将其发送出去,并在窗体中完成显示操作。
Private Sub sub_udp_send(ByRef data() As Byte,ByVal length As Int16) Dim ip_end_point As IPEndPoint Dim strsql As String Dim rst As ADODB.Recordset strsql = "select * from configuration_net where MINGCHENG = 'configuration_net'" rst = myADO.OpenRecordset(strsql) If Not rst.EOF Then ip_end_point = New IPEndPoint(IPAddress.Parse(rst.Fields("LocalIP_A").Value & "." & rst.Fields("LocalIP_B").Value & "." & rst.Fields("LocalIP_C").Value & "." & rst.Fields("LocalIP_D").Value),1000) End If rst.Close() Dim i As Int16 Dim strData As String Dim checksum As Int16 = 0 For i = 0 To length - 1 checksum = checksum + data(i) Next data(length) = checksum Mod 256 udp.Send(data,length + 1,ip_end_point) txtCommunicationData.Text = vbCrLf & txtCommunicationData.Text strData = "发送(" & TimeOfDay.ToLongTimeString() & “):” For i = 0 To length strData = strData & " " & common.OneToTwo(Hex(data(i))) Next txtCommunicationData.Text = vbCrLf & strData & txtCommunicationData.Text End Sub
6、在Me.Disposed方法中将SocketIsValid设置为False,以便完成在窗体退出时,退出线程。
Private Sub frm_configuration_uart_Disposed(sender As Object,e As EventArgs) Handles Me.Disposed SocketIsValid = False End Sub
通过以上程序设计,就可以轻松完成UDP的收发操作了。
原创性文章,转载请注明出处
CSDN:http://blog.csdn.net/qingwufeiyang12346。