Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Simple UDP client - UPnP Discover


  • Please log in to reply
1 reply to this topic
Guest2
  • Members
  • 12 posts
  • Last active: Oct 25 2014 12:27 AM
  • Joined: 09 Nov 2012

Hi All :) since I saw a lot of confusion about the UDP implementation, and not even the german forum versions work properly.. ;) here my version. Enjoy! :D

Please, look at it as a kind of "quintessential" implementation of a UDP client (tested on Autohotkey Basic _only_ )

INADDR=255.255.255.255
; INADDR=192.168.0.1
PORT=1900
AF_INET := 2
PF_INET := 2
SOCK_DGRAM := 2
IPPROTO_UDP := 17
MSG_DONTROUTE := 4
SOL_SOCKET := 0xFFFF
SO_BROADCAST := 0x0020

SendData=
(
M-SEARCH * HTTP/1.1`r
HOST: 239.255.255.250:1900`r
MAN: "ssdp:discover"`r
MX: 3`r
ST:upnp:rootdevice`r
`r

)

VarSetCapacity(wsaData, 32)
If (DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) != 0 or ErrorLevel != 0)
	Msgbox,16,, % "WSAStartup=" . DllCall("Ws2_32\WSAGetLastError") ;%
socket := DllCall("Ws2_32\socket", "Int", PF_INET, "Int", SOCK_DGRAM, "Int", IPPROTO_UDP)
if socket = -1
	Msgbox,16,, % "socket=" . DllCall("Ws2_32\WSAGetLastError") ;%
SizeOfSocketAddress = 16
VarSetCapacity(SocketAddress, SizeOfSocketAddress) ; struct sockaddr_in=16 bytes
NumPut(AF_INET, SocketAddress, 0, "Short")
NumPut(DllCall("Ws2_32\htons", "UShort", PORT), SocketAddress, 2, "UShort")
NumPut(DllCall("Ws2_32\inet_addr", "Str", INADDR), SocketAddress, 4, "UInt")
SizeOfB = 16
VarSetCapacity(B,SizeOfB)
B = 1
If DllCall("Ws2_32\setsockopt", "UInt", socket, "UInt", SOL_SOCKET, "UInt", SO_BROADCAST, "UInt", &B, "Int", SizeOfB) != 0
	Msgbox,16,, % "setsockopt=" . DllCall("Ws2_32\WSAGetLastError") ;%

DataBufLength := StrLen(SendData)
VarSetCapacity(DataBuf, DataBufLength)
DataBuf := SendData
result := DllCall("Ws2_32\sendto", "UInt", socket, "UInt", &DataBuf, "Int", DataBufLength, "Int", MSG_DONTROUTE, "UInt", &SocketAddress, "Int", SizeOfSocketAddress)
If result != %DataBufLength%
	Msgbox,16,, % "sendto=" . DllCall("Ws2_32\WSAGetLastError") ;%

_final=
VarSetCapacity(recvdata, 2048, 0)
VarSetCapacity(fromaddr, 16, 0)
VarSetCapacity(buff, 1024) ; half of recvdata
loop 40
	{
	sleep 200
	If DllCall("Ws2_32\recvfrom", "UInt", socket, "Str", recvdata, "UInt", 2048, "UInt", 0, "UInt", &fromaddr, "UInt", &buff) != -1
		{
		_ip=
		loop 4
			_ip.=NumGet(fromaddr, 4+A_Index-1, "UChar") "."
		_final=%_final%[%_ip%=%recvdata%]
		break
		}
	;else
	;	{
	;	_tmp:=DllCall("Ws2_32\WSAGetLastError")
	;	FileAppend ,[%_tmp%], test.txt
	;	}
	}

DllCall("Ws2_32\closesocket", "UInt", socket)
DllCall("Ws2_32\WSACleanup")
Msgbox %_final%
ExitApp



jmone1
  • Members
  • 33 posts
  • Last active: Oct 23 2015 06:29 AM
  • Joined: 14 Jun 2014
This is not working for me but appears to be a Syntax issue, as when I uncomment out the final else section, I'm getting from _tmp:=DllCall("Ws2_32\WSAGetLastError") an error 10022:
 
Invalid argument.
Some invalid argument was supplied (for example, specifying an invalid level to thesetsockopt function). In some instances, it also refers to the current state of the socket—for instance, calling accept on a socket that is not listening.