#include <GUIConstantsEx.au3>
Global $S_Socket, $C_Socket
Example()
Func Example()
UDPStartup()
Local $sReceived, $maxlen
Local $hGUI = GUICreate("UDP通讯示例")
Local $idEXIT = GUICtrlCreateButton("退出", 310, 370, 85, 25)
Local $Label1 = GUICtrlCreateLabel("", 10, 10, 160, 25)
Local $Label2 = GUICtrlCreateLabel("", 10, 42, 160, 25)
Local $Label3 = GUICtrlCreateLabel("Server 返回消息:", 10, 74, 160, 25)
GUISetState(@SW_SHOW, $hGUI)
$S_Socket = _UDPBind("0.0.0.0", 0)
If @error Then Exit MsgBox(0, "", "服务端:" & @CRLF & "无法绑定, 错误代码: " & @error)
GUICtrlSetData($Label1, "Server 监听端口:" & @extended)
$C_Socket = _UDPOpen("127.0.0.1", $S_Socket[3])
If @error Then Exit MsgBox(0, "", "客户端:" & @CRLF & "无法连接, 错误代码: " & @error)
GUICtrlSetData($Label2, "Client 监听端口:" & @extended)
AdlibRegister("_Time", 1000)
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $idEXIT
ExitLoop
EndSwitch
$maxlen = _Datelen($S_Socket)
If $maxlen Then
$sReceived = _UDPRecv($S_Socket, $maxlen, 2)
$S_Socket[2] = $sReceived[1]
$S_Socket[3] = $sReceived[2]
UDPSend($S_Socket, @HOUR & ":" & @MIN & ":" & @SEC)
EndIf
$maxlen = _Datelen($C_Socket)
If $maxlen Then
$sReceived = _UDPRecv($C_Socket, $maxlen)
GUICtrlSetData($Label3, "Server 返回消息:" & $sReceived)
EndIf
WEnd
UDPCloseSocket($S_Socket)
UDPCloseSocket($C_Socket)
UDPShutdown()
GUIDelete($hGUI)
EndFunc ;==>Example
Func _Time()
UDPSend($C_Socket, @SEC)
EndFunc ;==>_Time
Func _UDPOpen($sIPAddr, $iPort)
Local $aSocket = _UDPBind("0.0.0.0", 0)
$aSocket[2] = $sIPAddr
$aSocket[3] = $iPort
Return SetError(@error, @extended, $aSocket)
EndFunc ;==>_UDPOpen
Func _UDPBind($sIPAddr, $iPort)
Local $aSocket, $loop
If $iPort = 0 Then
Do
$loop += 1
$iPort = Random(49152, 65535, 1)
$aSocket = UDPBind($sIPAddr, $iPort)
If $loop > 15000 Then ExitLoop
Until @error <> 10048
Else
$aSocket = UDPBind($sIPAddr, $iPort)
EndIf
If @error Then Return SetError(@error, 0, $aSocket)
DllCall("Ws2_32.dll", "long", "setsockopt", "handle", $aSocket[1], "long", 0xffff, "long", 0x20, "long*", 1, "long*", 4) ;允许广播地址
Return SetError(0, $aSocket[3], $aSocket)
EndFunc ;==>_UDPBind
Func _UDPRecv(ByRef $aSocket, $maxlen, $flag = 0)
Local $sRecv = UDPRecv($aSocket, $maxlen, $flag)
Return SetError(@error, 0, $sRecv)
EndFunc ;==>_UDPRecv
Func _Datelen(ByRef $aSocket)
Local $aRet = DllCall("Ws2_32.dll", "int", "ioctlsocket", "uint", $aSocket[1], "long", 0x4004667F, "ulong*", 0) ;查询接收缓冲区数据长度
If Not @error Then Return SetError(0, 0, $aRet[3])
Return SetError(@error, 0, 0)
EndFunc ;==>_Datelen