Jump to content

How to receive datagram ? (UDP on AnyIPAddress)


Recommended Posts

Hi,
I'm trying to receive a response from a broadcast.

I'm unable to make to the UDPRecv function work, this one returns an error of -1 (and of course like the bugged function TCPRecv, there is no WSA error).

Here is the simple reproducer :

Example()

Func Example()
    UDPStartup()

    Local $aBindSocket = UDPBind("0.0.0.0", 65432)
    If @error Then Return False

    Local $hBroadcastTimer = TimerInit(), $iBroadcastInterval = 15000

    While TimerDiff($hBroadcastTimer) < $iBroadcastInterval
        $bResponse = UDPRecv($aBindSocket, 1024)
        If @error Then
            ConsoleWrite("@error: " & @error & @CRLF)
            Return False
        EndIf

        If BinaryLen($bResponse) = 0 Then ContinueLoop
        ConsoleWrite("+response" & @CRLF)
    WEnd

    UDPShutdown()
EndFunc   ;==>Example

Thanks in advance for anyhelp.

Edited by FireFox
Link to comment
Share on other sites

Lately, I have been using this code. It seems to be working across all AutoIt versions.

Perhaps it might be useful to you. Modify it to suit your needs.

; Cross-Version Solution
...

Local $NewVersion = Number(Number(StringReplace(@AutoItVersion, '.', '')) > 3381)
Local $nTCPRecv_Error, $nWSA_Error

...

TCPRecv(...)

$nTCPRecv_Error = @error
Select
    Case $nTCPRecv_Error = 0; no error - pass thru
    Case ($nTCPRecv_Error = -1) And $NewVersion; blank string >= v3.3.10.0
        $nTCPRecv_Error = 0; reset error - pass thru
    Case Else; -2, -3 and WSA Errors
        $nWSA_Error = _WSA_GetLastError()
        ExitLoop
EndSelect

...

Func _WSA_GetLastError()
    Local $a = DllCall($hWS2_32, 'int', 'WSAGetLastError')
    If @error Then Return -1
    Return $a[0]
EndFunc

...

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Hi,

Thanks for your code, unfortunately I don't receive anything.

My code must be wrong but I don't know where  :ermm: , I'm looking at doing it with winapi calls.

Edited by FireFox
Link to comment
Share on other sites

  • 8 months later...

Hi,

I'm trying to receive a response from a broadcast.

I'm unable to make to the UDPRecv function work, this one returns an error of -1 (and of course like the bugged function TCPRecv, there is no WSA error).

Here is the simple reproducer :

Example()

Func Example()
    UDPStartup()

    Local $aBindSocket = UDPBind("0.0.0.0", 65432)
    If @error Then Return False

    Local $hBroadcastTimer = TimerInit(), $iBroadcastInterval = 15000

    While TimerDiff($hBroadcastTimer) < $iBroadcastInterval
        $bResponse = UDPRecv($aBindSocket, 1024)
        If @error Then
            ConsoleWrite("@error: " & @error & @CRLF)
            Return False
        EndIf

        If BinaryLen($bResponse) = 0 Then ContinueLoop
        ConsoleWrite("+response" & @CRLF)
    WEnd

    UDPShutdown()
EndFunc   ;==>Example

Thanks in advance for anyhelp.

 

Hey, just wanted to share that I ran into this problem too. It appears to be a bug in the UDPRecv command but it works perfectly fine! Here's working code right now on 3.3.10.2.

;UDP Listener
#include <Array.au3>
if UDPStartup() <> 1 Then
   msgbox(0,"ERROR","Could not start the network stack")
   Exit
EndIf

Func OnAutoItExit()
    UDPShutdown()
 EndFunc
 
$socket=UDPBind("0.0.0.0",65535)
if @error Then
   $iError=@error
   msgbox(0,"ERROR","UDP Bind "&$iError)
   Exit
EndIf

$socket2=UDPOpen("255.255.255.255",65535,1)
if @error Then
   $iError=@error
   msgbox(0,"ERROR","UDP Open "&$iError)
   Exit
EndIf

_ArrayDisplay($socket)
_ArrayDisplay($socket2)
UDPSend($socket2,"TEST")
$timer=TimerInit()
$lastDiff=0
while 1
   $data=UDPRecv($socket,1024,2)
   if $data = "" and @error < -1 Then
      $iError=@error
      msgbox(0,"ERROR","UDP Read "&$iError)
      Exit
   EndIf
   if isarray($data) and BinaryLen($data[0]) > 0 then consolewrite("UDP DATA ("&$data[1]&":"&$data[2]&"): "&BinaryToString($data[0])&@CRLF)
   $stamp=TimerDiff($timer)/1000
   if $stamp > $lastDiff+1 Then
      UDPSend($socket2,String("Stamp:"&$stamp))
      $lastDiff=$stamp
   EndIf
WEnd

If you ignore the -1 (likely indicating that aSocket[1] is incorrect) and just look for data when it arrives, it appears to work just fine. I can start a couple copies of this on a few machines in the network and see all the different stamps from the different devices showing up on all outputs without an issue. I even Wireshark'd the network and I can see the messages flowing in the clear. I have no idea why it's returning a -1 when it should realistically be returning "" and no @error when there's no data received on 0.0.0.0 but it freaks out nonetheless.

To reiterate, if you UDPBind 0.0.0.0, every subsequent UDPRecv request on the resulting socket will return "" and @error = -1 unless there is data to be received, then you get an array returned with all the information with no problems, but the instant there's no more data to read, you get an @error = -1 once again. Weird. I've come to treat -1 with 0.0.0.0 as NO DATA instead of a problem with the aSocket variable and it works fine for me.

-Cynagen

Edited by Cynagen

Blah, blah, blah... lip service... lip service.Working on a number of projects right now, just waiting for my time to post them here on AutoIt forums.

Link to comment
Share on other sites

Hey, just wanted to share that I ran into this problem too. It appears to be a bug in the UDPRecv command but it works perfectly fine! Here's working code right now on 3.3.10.2.

;UDP Listener
#include <Array.au3>
if UDPStartup() <> 1 Then
   msgbox(0,"ERROR","Could not start the network stack")
   Exit
EndIf

Func OnAutoItExit()
    UDPShutdown()
 EndFunc
 
$socket=UDPBind("0.0.0.0",65535)
if @error Then
   $iError=@error
   msgbox(0,"ERROR","UDP Bind "&$iError)
   Exit
EndIf

$socket2=UDPOpen("255.255.255.255",65535,1)
if @error Then
   $iError=@error
   msgbox(0,"ERROR","UDP Open "&$iError)
   Exit
EndIf

_ArrayDisplay($socket)
_ArrayDisplay($socket2)
UDPSend($socket2,"TEST")
$timer=TimerInit()
$lastDiff=0
while 1
   $data=UDPRecv($socket,1024,2)
   if $data = "" and @error < -1 Then
      $iError=@error
      msgbox(0,"ERROR","UDP Read "&$iError)
      Exit
   EndIf
   if isarray($data) and BinaryLen($data[0]) > 0 then consolewrite("UDP DATA ("&$data[1]&":"&$data[2]&"): "&BinaryToString($data[0])&@CRLF)
   $stamp=TimerDiff($timer)/1000
   if $stamp > $lastDiff+1 Then
      UDPSend($socket2,String("Stamp:"&$stamp))
      $lastDiff=$stamp
   EndIf
WEnd

If you ignore the -1 (likely indicating that aSocket[1] is incorrect) and just look for data when it arrives, it appears to work just fine. I can start a couple copies of this on a few machines in the network and see all the different stamps from the different devices showing up on all outputs without an issue. I even Wireshark'd the network and I can see the messages flowing in the clear. I have no idea why it's returning a -1 when it should realistically be returning "" and no @error when there's no data received on 0.0.0.0 but it freaks out nonetheless.

To reiterate, if you UDPBind 0.0.0.0, every subsequent UDPRecv request on the resulting socket will return "" and @error = -1 unless there is data to be received, then you get an array returned with all the information with no problems, but the instant there's no more data to read, you get an @error = -1 once again. Weird. I've come to treat -1 with 0.0.0.0 as NO DATA instead of a problem with the aSocket variable and it works fine for me.

-Cynagen

 

Upgraded to 3.3.12.0, same exact symptoms and work-around.

Blah, blah, blah... lip service... lip service.Working on a number of projects right now, just waiting for my time to post them here on AutoIt forums.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...