前面几篇日志中,介绍了有关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), 929)
Else
ip_end_point = New IPEndPoint(IPAddress.Parse("192.168.0.1"), 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的收发操作了。
原创性文章,转载请注明出处
优快云:http://blog.youkuaiyun.com/qingwufeiyang12346。