Sign in to follow this  
Followers 0
FireFox

How to receive datagram ? (UDP on AnyIPAddress)

5 posts in this topic

#1 ·  Posted (edited)

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

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
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

...

Make yourself sheep and the wolves will eat you - Benjamin Franklin

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

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.

Share this post


Link to post
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.

Share this post


Link to post
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
Sign in to follow this  
Followers 0