微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

VB.net应用技巧8: 使用UdpClient完成UDP数据收发

前面几篇日志中,介绍了有关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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强制返回为文本 -------------------------------- 数字类型的格式化 --------------------------------     固定格式参数:     General Number 普通数字,如可以用来去掉千位分隔号     format$("100,1
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办法, Format 或者FormatDateTime 竟然结果和系统设置的区域语言的日期和时间格式相关。意思是尽管你用诸如 Format(Now, "MM/dd/yyyy"),如果系统的设置格式区域语言的日期和时间格式分隔符是"-",那他还会显示为 MM-dd-yyyy     只有拼凑: <%response.write
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace My ‘全局错误处理,新的解决方案直接添加本ApplicationEvents.vb 到工程即可 ‘添加后还需要一个From用来显示错误。如果到这步还不会则需要先打好基础啦 ‘======================================================== ‘以下事件
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用的爽呀,这篇文章写与2011年,看来我以前没有认真去找这个方法呀。 https://blog.csdn.net/chzjxgd/article/details/6176325 金蝶K3 BOS的插件官方是用VB6编写的,如果  能用.Net下的语言工具开发BOS插件是一件很愉快的事情,其中缘由不言而喻,而本文则是个人首创,实现在了用V
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选中的单元格进行处理 Dim m As Range, tmpStr As String, s As String Dim x As Integer, y As Integer, subStr As String If MsgBox("确定要分列处理吗?请确定分列的数据会覆盖它后面的单元格!", _
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single) 2 Dim path As String, hash As String 3 For Each fil
  Imports MySql.Data.MySqlClient Public Class Form1 ‘ GLOBAL DECLARATIONS Dim conString As String = "Server=localhost;Database=net2;Uid=root;Pwd=123456;" Dim con As New MySqlConnection
‘導入命名空間 Imports ADODB Imports Microsoft.Office.Interop   Private Sub A1() Dim Sql As String Dim Cnn As New ADODB.Connection Dim Rs As New ADODB.Recordset Dim S As String   S = "Provider=OraOLEDB.Oracl
Imports System.IO Imports System.Threading Imports System.Diagnostics Public Class Form1 Dim A(254) As String    Function ping(ByVal IP As Integer) As String Dim IPAddress As String IPAddress = "10.0.
VB运行EXE程序,并等待其运行结束 参考:https://blog.csdn.net/useway/article/details/5494084 Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Pr