mayans005 2023-03-23 14:56 采纳率: 0%
浏览 14

关于#UDP#同步非阻塞接收的问题,如何解决?

想用VB6做一个UDP接收程序,可以接收局域网内所有终端向该程序指定端口发送的UDP数据。
目前使用下面的代码,遇到的问题是等待接收的时候,程序就会假死,无法进行任何其他操作。希望程序监听UDP数据的时候,可以正常处理其他请求。
在网上找到了用WINSOCK API实现同步非阻塞方式的网络通讯,但不知道如何改成我需要的。
请大家帮忙。

Attribute VB_Name = "modUDPRead"
Option Explicit
Private Const DEFAULT_QUEUE = 1024
Private Const DEFAULT_WAIT_TIME = 50


Private Const WSA_DescriptionLen = 256
Private Const WSA_DescriptionSize = WSA_DescriptionLen + 1
Private Const WSA_SYS_STATUS_LEN = 128
Private Const WSA_SysStatusSize = WSA_SYS_STATUS_LEN + 1
Private Const AF_INET = 2

Private Const SOCK_DGRAM = 2 'UDP
Private Const IPPROTO_UDP = 17 'UDP
Private Const INADDR_ANY As Long = &H0
Private Const IPPROTO_IP As Long = 0
Private Const IP_ADD_MEMBERSHIP As Long = 5

Private Const INADDR_NONE = &HFFFF
Private Const SOCKET_ERROR = -1

Private Type HostEnt
    hName As Long
    hAliases As Long
    hAddrType As Integer
    hLength As Integer
    hAddrList As Long
End Type

Private Type SockAddr
    Sin_Family As Integer
    Sin_Port As Integer
    Sin_Addr As Long
    Sin_Zero(7) As Byte
End Type

Private Type WSADataType
    wVersion As Integer
    wHighVersion As Integer
    szDescription As String * WSA_DescriptionSize
    szSystemStatus As String * WSA_SysStatusSize
    iMaxSockets As Integer
    iMaxUdpDg As Integer
    lpVendorInfo As Long
End Type

Private Type IP_MREQ
  imr_multiaddr As Long
  imr_interface As Long
End Type






Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 
Private Declare Function timeGetTime Lib "winmm.dll" () As Long 

Private Declare Function CloseSocket Lib "ws2_32.dll" Alias "closesocket" (ByVal hSocket As Long) As Long
Private Declare Function Connect Lib "ws2_32.dll" Alias "connect" (ByVal hSocket As Long, Addr As SockAddr, ByVal NameLen As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GetHostByName Lib "ws2_32.dll" Alias "gethostbyname" (ByVal HostName As String) As Long
Private Declare Function Htons Lib "ws2_32.dll" Alias "htons" (ByVal HostShort As Integer) As Integer
Private Declare Function iNet_Addr Lib "wsock32.dll" Alias "inet_addr" (ByVal s As String) As Long
Private Declare Function Recv Lib "ws2_32.dll" Alias "recv" (ByVal hSocket As Long, Buf As Any, ByVal BufLen As Long, ByVal Flags As Long) As Long
Private Declare Function Send Lib "ws2_32.dll" Alias "send" (ByVal hSocket As Long, Buf As Any, ByVal BufLen As Long, ByVal Flags As Long) As Long
Private Declare Function Socket Lib "ws2_32.dll" Alias "socket" (ByVal af As Long, ByVal sType As Long, ByVal Protocol As Long) As Long
Private Declare Function WSACleanup Lib "ws2_32.dll" () As Long
Private Declare Function WSAStartup Lib "ws2_32.dll" (ByVal wVR As Long, lpWSAD As WSADataType) As Long


Private Declare Function bind Lib "wsock32.dll" (ByVal s As Long, Addr As SockAddr, ByVal NameLen As Long) As Long
Private Declare Function setsockopt Lib "wsock32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, ByRef optval As Any, ByVal optlen As Long) As Long


Public Sub UDPClose(ByRef Handle As Long)
    CloseSocket Handle
    WSACleanup
    Handle = -1
End Sub

Public Function UDPOpen(ByVal Host As String, Optional ByVal Port As Long = 502) As Long
    Dim WSAData As WSADataType, SA As SockAddr, Result As Long, iResult As Long
    If WSAStartup(&H202, WSAData) <> 0 Then
        WSACleanup
    Else
        If (InStr(Host, ":") > 0) Then
            If IsNumeric(Right(Host, Len(Host) - InStr(Host, ":"))) = True Then
                Port = CLng(Right(Host, Len(Host) - InStr(Host, ":")))
            End If
            Host = Left(Host, InStr(Host, ":") - 1)
        End If
        Result = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
        

        Dim mreq As IP_MREQ
        mreq.imr_multiaddr = iNet_Addr("224.0.0.1")
        mreq.imr_interface = iNet_Addr(Host)
        iResult = setsockopt(Result, IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq, Len(mreq))
        If iResult = -1 Then
            CloseSocket Result
            WSACleanup
            Result = -1
        End If
            
        
        SA.Sin_Family = AF_INET
        SA.Sin_Port = Htons(CInt("&H" & Hex(Port)))
        SA.Sin_Addr = INADDR_ANY
        iResult = bind(Result, SA, Len(SA))
        If iResult = -1 Then
            CloseSocket Result
            WSACleanup
            Result = -2
        End If
        
        
    End If
    UDPOpen = Result
End Function

Public Function UDPReadByte(ByVal Handle As Long, Optional ByVal WaitTime As Long = DEFAULT_WAIT_TIME) As Byte()
    Dim T As Double, Result() As Byte, I As Integer
    If Handle = -1 Then Exit Function
    ReDim Result(DEFAULT_QUEUE - 1)
    If WaitTime > 0 Then
        DoEvents
        Sleep2 WaitTime
    End If
    I = Recv(Handle, Result(0), UBound(Result) + 1, 0)
    If I > 0 Then
        ReDim Preserve Result(I - 1)
        UDPReadByte = Result
    End If
End Function


Public Function UDPReadString(ByVal Handle As Long, Optional ByVal WaitTime As Long = DEFAULT_WAIT_TIME) As String
    Dim Data() As Byte
    Data = UDPReadByte(Handle, WaitTime)
    UDPReadString = StrConv(Data, vbUnicode)
End Function


Public Function UDPReadHex(ByVal Handle As Long, Optional ByVal WaitTime As Long = DEFAULT_WAIT_TIME) As String
    Dim Data() As Byte, Result As String, I As Long
    Data = UDPReadByte(Handle, WaitTime)
    For I = 0 To UBound(Data)
        Result = Result & IIf(Data(I) < 16, "0", "") & UCase(Hex(Data(I)))
    Next
    UDPReadHex = Result
End Function


Public Function Sleep2(T As Long)
    Dim Savetime As Long
    Savetime = timeGetTime 
    While timeGetTime < Savetime + T 
      Call Sleep(1) 
        DoEvents 
    Wend
End Function



  • 写回答

2条回答 默认 最新

  • 於黾 2023-03-23 15:56
    关注

    多线程呀
    或者改用异步

    评论

报告相同问题?

问题事件

  • 修改了问题 3月23日
  • 创建了问题 3月23日

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装