• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

AutoIT Tcp udf

Status
Not open for further replies.

Skydno

NOT IN SPAIN
User
Joined
Jan 14, 2015
Messages
33
Reputation
0
Reaction score
319
Points
53
Credits
0
‎10 Years of Service‎
66%
[HIDE-THANKS]

Code:
>#cs ----------------------------------------------------------------------------

AutoIt Version: 3.3.0.0
Author:         Kip

Script Function:
TCP UDF v3

#ce ----------------------------------------------------------------------------

#cs

Functions:

_TCP_Server_Create($iPort, $sIP="0.0.0.0")
_TCP_Server_Broadcast($sData)
_TCP_Server_ClientList()
_TCP_Server_ClientIP($hSocket)
_TCP_Server_DisconnectClient($hSocket)
_TCP_Server_Stop()


_TCP_Client_Create($sIP , $iPort)
_TCP_Client_Stop($hSocket)


_TCP_Send($hSocket, $sText)
_TCP_RegisterEvent($hSocket, $iEvent, $sFunction)


Register event values:

$TCP_SEND				; Function ($hSocket, $iError)
$TCP_RECEIVE			; Function ($hSocket, $sReceived, $iError)
$TCP_CONNECT			; Function ($hSocket, $iError)					=> Client only
$TCP_DISCONNECT			; Function ($hSocket, $iError)
$TCP_NEWCLIENT			; Function ($hSocket, $iError) 					=> Server only


#ce


Global Const $FD_READ = 1
Global Const $FD_WRITE = 2
Global Const $FD_OOB = 4
Global Const $FD_ACCEPT = 8
Global Const $FD_CONNECT = 16
Global Const $FD_CLOSE = 32
Local $hWs2_32 = -1

Global Const $TCP_SEND = 1
Global Const $TCP_RECEIVE = 2
Global Const $TCP_CONNECT = 4
Global Const $TCP_DISCONNECT = 8
Global Const $TCP_NEWCLIENT = 16


TCPStartup()
Global Const $__TCP_WINDOW = GUICreate("Async Sockets UDF")
Global $__TCP_SOCKETS[1][7]


Func _TCP_Server_Create($iPort, $sIP = "0.0.0.0")

$hListenSocket = _ASocket()


_ASockSelect($hListenSocket, $__TCP_WINDOW, 0x0400, $FD_ACCEPT)
GUIRegisterMsg(0x0400, "__TCP_OnAccept")


_ASockListen($hListenSocket, $sIP, $iPort)

$__TCP_SOCKETS[0][0] = $hListenSocket
$__TCP_SOCKETS[0][1] = 0x0400

Return $hListenSocket

EndFunc   ;==>_TCP_Server_Create


Func __TCP_OnAccept($hWnd, $iMsgID, $WParam, $LParam)

Local $hSocket = $WParam
Local $iError = _HiWord($LParam)
Local $iEvent = _LoWord($LParam)


If $iMsgID = $__TCP_SOCKETS[0][1] Then

	If $iEvent = $FD_ACCEPT Then

		If Not $iError Then

			ReDim $__TCP_SOCKETS[uBound($__TCP_SOCKETS) + 1][7]
			$uBound = UBound($__TCP_SOCKETS)

			$hClient = TCPAccept($hSocket)

			_ASockSelect($hClient, $__TCP_WINDOW, 0x0400 + $uBound - 1, BitOR($FD_READ, $FD_WRITE, $FD_CLOSE))
			GUIRegisterMsg(0x0400 + $uBound - 1, "__TCP_Server_OnSocketEvent")

			$__TCP_SOCKETS[uBound($__TCP_SOCKETS) - 1][0] = $hClient
			$__TCP_SOCKETS[uBound($__TCP_SOCKETS) - 1][1] = 0x0400 + $uBound - 1

			Call($__TCP_SOCKETS[0][6], $hClient, $iError)

		Else

			Call($__TCP_SOCKETS[0][6], 0, $iError)

		EndIf

	ElseIf $iEvent = $FD_CONNECT Then

		Call($__TCP_SOCKETS[0][4], $hSocket, $iError)

	EndIf

EndIf

EndFunc   ;==>__TCP_OnAccept


Func _TCP_Client_Stop($hSocket)

$iElement = 0

For $i = 1 To UBound($__TCP_SOCKETS) - 1

	If $__TCP_SOCKETS[$i][0] = $hSocket Then
		$iElement = $i
		ExitLoop
	EndIf

Next

If $iElement Then

	_ASockShutdown($__TCP_SOCKETS[$iElement][0])
	TCPCloseSocket($__TCP_SOCKETS[$iElement][0])

	___ArrayDelete($__TCP_SOCKETS, $iElement)

	Return 1

EndIf

Return 0

EndFunc   ;==>_TCP_Client_Stop


Func _TCP_Server_Stop()

_ASockShutdown($__TCP_SOCKETS[0][0])
TCPCloseSocket($__TCP_SOCKETS[0][0])

$__TCP_SOCKETS[0][0] = ""
$__TCP_SOCKETS[0][1] = ""
$__TCP_SOCKETS[0][2] = ""
$__TCP_SOCKETS[0][3] = ""
$__TCP_SOCKETS[0][4] = ""
$__TCP_SOCKETS[0][5] = ""
$__TCP_SOCKETS[0][6] = ""

For $i = UBound($__TCP_SOCKETS) - 1 To 1 Step -1
	___ArrayDelete($__TCP_SOCKETS, $i)
Next

Return 1

EndFunc   ;==>_TCP_Server_Stop


Func __TCP_Server_OnSocketEvent($hWnd, $iMsgID, $WParam, $LParam)

Local $hSocket = $WParam
Local $iError = _HiWord($LParam)
Local $iEvent = _LoWord($LParam)
Local $sData

$hSocket = 0
$iElement = 0

For $i = 1 To UBound($__TCP_SOCKETS) - 1

	If $__TCP_SOCKETS[$i][1] = $iMsgID Then
		$hSocket = $__TCP_SOCKETS[$i][0]
		$iElement = $i
		ExitLoop
	EndIf

Next

If $hSocket Then

	Switch $iEvent
		Case $FD_READ
			$sRecv = ""
			$sData = ""
			Do
				$sRecv = TCPRecv($hSocket, 2048)
				$sData = $sData & $sRecv
				ConsoleWrite(".")
			Until $sRecv = ""
			Call($__TCP_SOCKETS[0][2], $hSocket, $sData, $iError)

		Case $FD_WRITE

			Call($__TCP_SOCKETS[0][3], $hSocket, $iError)

		Case $FD_CLOSE

			_ASockShutdown($hSocket)
			TCPCloseSocket($hSocket)

			Call($__TCP_SOCKETS[0][5], $hSocket, $iError)

			___ArrayDelete($__TCP_SOCKETS, $iElement)

	EndSwitch

EndIf

EndFunc   ;==>__TCP_Server_OnSocketEvent


Func _TCP_Server_DisconnectClient($hSocket)

$iElement = 0

For $i = 1 To UBound($__TCP_SOCKETS) - 1

	If $__TCP_SOCKETS[$i][0] = $hSocket Then
		$iElement = $i
		ExitLoop
	EndIf

Next

If $iElement Then

	_ASockShutdown($hSocket)
	TCPCloseSocket($hSocket)

	___ArrayDelete($__TCP_SOCKETS, $iElement)

	Return 1

EndIf

Return 0

EndFunc   ;==>_TCP_Server_DisconnectClient


Func _TCP_Server_ClientList()

Local $aReturn[1]

For $i = 1 To UBound($__TCP_SOCKETS) - 1
	If $__TCP_SOCKETS[$i][0] Then
		ReDim $aReturn[uBound($aReturn) + 1]
		$aReturn[uBound($aReturn) - 1] = $__TCP_SOCKETS[$i][0]
	EndIf
Next

$aReturn[0] = UBound($aReturn) - 1

Return $aReturn

EndFunc   ;==>_TCP_Server_ClientList



Func _TCP_Server_Broadcast($sData)

For $i = 1 To UBound($__TCP_SOCKETS) - 1

	If $__TCP_SOCKETS[$i][0] Then TCPSend($__TCP_SOCKETS[$i][0], $sData)

Next

EndFunc   ;==>_TCP_Server_Broadcast


Func _TCP_Client_Create($sIP, $iPort)

ReDim $__TCP_SOCKETS[uBound($__TCP_SOCKETS) + 1][7]
$uBound = UBound($__TCP_SOCKETS)

$hSocket = _ASocket()

$__TCP_SOCKETS[uBound($__TCP_SOCKETS) - 1][0] = $hSocket
$__TCP_SOCKETS[uBound($__TCP_SOCKETS) - 1][1] = 0x0400 + (UBound($__TCP_SOCKETS) - 1)

_ASockSelect($hSocket, $__TCP_WINDOW, 0x0400 + (UBound($__TCP_SOCKETS) - 1), BitOR($FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE))
GUIRegisterMsg(0x0400 + (UBound($__TCP_SOCKETS) - 1), "__TCP_Client_OnSocketEvent")
_ASockConnect($hSocket, $sIP, $iPort)

Return $hSocket

EndFunc   ;==>_TCP_Client_Create


Func _TCP_RegisterEvent($hSocket, $iEvent, $sFunction)

Local $iSelected = 0

If $__TCP_SOCKETS[0][0] Then

	$iSelected = 0

Else

	For $i = 0 To UBound($__TCP_SOCKETS) - 1
		If $__TCP_SOCKETS[$i][0] = $hSocket Then
			$iSelected = $i
			ExitLoop
		EndIf
	Next

	If Not $iSelected Then Return 0

EndIf

Switch $iEvent
	Case $TCP_SEND
		$__TCP_SOCKETS[$iSelected][3] = $sFunction
	Case $TCP_RECEIVE
		$__TCP_SOCKETS[$iSelected][2] = $sFunction
	Case $TCP_CONNECT
		$__TCP_SOCKETS[$iSelected][4] = $sFunction
	Case $TCP_DISCONNECT
		$__TCP_SOCKETS[$iSelected][5] = $sFunction
	Case $TCP_NEWCLIENT
		$__TCP_SOCKETS[$iSelected][6] = $sFunction
	Case Else
		Return 0
EndSwitch

Return 1


EndFunc   ;==>_TCP_RegisterEvent

Func _TCP_Server_ClientIP($hSocket)

Local $pSocketAddress, $aReturn

$pSocketAddress = DllStructCreate("short;ushort;uint;char[8]")
$aReturn = DllCall("Ws2_32.dll", "int", "getpeername", "int", $hSocket, "ptr", DllStructGetPtr($pSocketAddress), "int*", DllStructGetSize($pSocketAddress))
If @error Or $aReturn[0] <> 0 Then Return 0

$aReturn = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($pSocketAddress, 3))
If @error Then Return 0

$pSocketAddress = 0

Return $aReturn[0]

EndFunc   ;==>_TCP_Server_ClientIP


Func _TCP_Send($hSocket, $sText)

Return TCPSend($hSocket, $sText)

EndFunc   ;==>_TCP_Send



Func __TCP_Client_OnSocketEvent($hWnd, $iMsgID, $WParam, $LParam)

Local $iError = _HiWord($LParam)
Local $iEvent = _LoWord($LParam)

$hSocket = 0
$iElement = 0

For $i = 1 To UBound($__TCP_SOCKETS) - 1

	If $__TCP_SOCKETS[$i][1] = $iMsgID Then
		$hSocket = $__TCP_SOCKETS[$i][0]
		$iElement = $i
		ExitLoop
	EndIf

Next

If $hSocket Then

	Switch $iEvent
		Case $FD_READ; Data has arrived!
			$Recv = ""
			$sData = ""
			Do
				$sRecv = TCPRecv($hSocket, 2048)
				$sData = $sData & $sRecv
				ConsoleWrite(".")
			Until $sRecv = ""
			Call($__TCP_SOCKETS[$i][2], $hSocket, $sData, $iError)

			$sData = ""

		Case $FD_WRITE

			Call($__TCP_SOCKETS[$i][3], $hSocket, $iError)

		Case $FD_CONNECT

			Call($__TCP_SOCKETS[$i][4], $hSocket, $iError)

		Case $FD_CLOSE

			_ASockShutdown($hSocket)
			TCPCloseSocket($hSocket)

			Call($__TCP_SOCKETS[$i][5], $hSocket, $iError)

			___ArrayDelete($__TCP_SOCKETS, $iElement)

	EndSwitch

EndIf

EndFunc   ;==>__TCP_Client_OnSocketEvent



;==================================================================================================================
;
; Zatorg's Asynchronous Sockets UDF Starts from here.
;
;==================================================================================================================


Func _ASocket($iAddressFamily = 2, $iType = 1, $iProtocol = 6)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $hSocket = DllCall($hWs2_32, "uint", "socket", "int", $iAddressFamily, "int", $iType, "int", $iProtocol)
If @error Then
	SetError(1, @error)
	Return -1
EndIf
If $hSocket[0] = -1 Then
	SetError(2, _WSAGetLastError())
	Return -1
EndIf
Return $hSocket[0]
EndFunc   ;==>_ASocket

Func _ASockShutdown($hSocket)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "shutdown", "uint", $hSocket, "int", 2)
If @error Then
	SetError(1, @error)
	Return False
EndIf
If $iRet[0] <> 0 Then
	SetError(2, _WSAGetLastError())
	Return False
EndIf
Return True
EndFunc   ;==>_ASockShutdown

Func _ASockClose($hSocket)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "closesocket", "uint", $hSocket)
If @error Then
	SetError(1, @error)
	Return False
EndIf
If $iRet[0] <> 0 Then
	SetError(2, _WSAGetLastError())
	Return False
EndIf
Return True
EndFunc   ;==>_ASockClose

Func _ASockSelect($hSocket, $hWnd, $uiMsg, $iEvent)
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall( _
		$hWs2_32, _
		"int", "WSAAsyncSelect", _
		"uint", $hSocket, _
		"hwnd", $hWnd, _
		"uint", $uiMsg, _
		"int", $iEvent _
		)
If @error Then
	SetError(1, @error)
	Return False
EndIf
If $iRet[0] <> 0 Then
	SetError(2, _WSAGetLastError())
	Return False
EndIf
Return True
EndFunc   ;==>_ASockSelect

; Note: you can see that $iMaxPending is set to 5 by default.
; IT DOES NOT MEAN THAT DEFAULT = 5 PENDING CONNECTIONS
; 5 == SOMAXCONN, so don't worry be happy
Func _ASockListen($hSocket, $sIP, $uiPort, $iMaxPending = 5); 5 == SOMAXCONN => No need to change it.
Local $iRet
Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")

$stAddress = __SockAddr($sIP, $uiPort)
If @error Then
	SetError(@error, @extended)
	Return False
EndIf

$iRet = DllCall($hWs2_32, "int", "bind", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
If @error Then
	SetError(3, @error)
	Return False
EndIf
If $iRet[0] <> 0 Then
	$stAddress = 0; Deallocate
	SetError(4, _WSAGetLastError())
	Return False
EndIf

$iRet = DllCall($hWs2_32, "int", "listen", "uint", $hSocket, "int", $iMaxPending)
If @error Then
	SetError(5, @error)
	Return False
EndIf
If $iRet[0] <> 0 Then
	$stAddress = 0; Deallocate
	SetError(6, _WSAGetLastError())
	Return False
EndIf

Return True
EndFunc   ;==>_ASockListen

Func _ASockConnect($hSocket, $sIP, $uiPort)
Local $iRet
Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")

$stAddress = __SockAddr($sIP, $uiPort)
If @error Then
	SetError(@error, @extended)
	Return False
EndIf

$iRet = DllCall($hWs2_32, "int", "connect", "uint", $hSocket, "ptr", DllStructGetPtr($stAddress), "int", DllStructGetSize($stAddress))
If @error Then
	SetError(3, @error)
	Return False
EndIf

$iRet = _WSAGetLastError()
If $iRet = 10035 Then; WSAEWOULDBLOCK
	Return True; Asynchronous connect attempt has been started.
EndIf
SetExtended(1); Connected immediately
Return True
EndFunc   ;==>_ASockConnect

; A wrapper function to ease all the pain in creating and filling the sockaddr struct
Func __SockAddr($sIP, $iPort, $iAddressFamily = 2)
Local $iRet
Local $stAddress

If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")

$stAddress = DllStructCreate("short; ushort; uint; char[8]")
If @error Then
	SetError(1, @error)
	Return False
EndIf

DllStructSetData($stAddress, 1, $iAddressFamily)
$iRet = DllCall($hWs2_32, "ushort", "htons", "ushort", $iPort)
DllStructSetData($stAddress, 2, $iRet[0])
$iRet = DllCall($hWs2_32, "uint", "inet_addr", "str", $sIP)
If $iRet[0] = 0xffffffff Then; INADDR_NONE
	$stAddress = 0; Deallocate
	SetError(2, _WSAGetLastError())
	Return False
EndIf
DllStructSetData($stAddress, 3, $iRet[0])

Return $stAddress
EndFunc   ;==>__SockAddr

Func _WSAGetLastError()
If $hWs2_32 = -1 Then $hWs2_32 = DllOpen("Ws2_32.dll")
Local $iRet = DllCall($hWs2_32, "int", "WSAGetLastError")
If @error Then
	ConsoleWrite("+> _WSAGetLastError(): WSAGetLastError() failed. Script line number: " & @ScriptLineNumber & @CRLF)
	SetExtended(1)
	Return 0
EndIf
Return $iRet[0]
EndFunc   ;==>_WSAGetLastError


; Got these here:
; http://www.autoitscript.com/forum/index.php?showtopic=5620&hl=MAKELONG
Func _MakeLong($LoWord, $HiWord)
Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF)); Thanks Larry
EndFunc   ;==>_MakeLong

Func _HiWord($Long)
Return BitShift($Long, 16); Thanks Valik
EndFunc   ;==>_HiWord

Func _LoWord($Long)
Return BitAND($Long, 0xFFFF); Thanks Valik
EndFunc   ;==>_LoWord


; ========================================= Array functions

; #FUNCTION# ====================================================================================================================
; Name...........: _ArrayDelete
; Description ...: Deletes the specified element from the given array.
; Syntax.........: _ArrayDelete(ByRef $avArray, $iElement)
; Parameters ....: $avArray  - Array to modify
;                  $iElement - Element to delete
; Return values .: Success - New size of the array
;                  Failure - 0, sets @error to:
;                  |1 - $avArray is not an array
;                  |3 - $avArray has too many dimensions (only up to 2D supported)
;                  |(2 - Deprecated error code)
; Author ........: Cephas 
; Modified.......: Jos van der Zande  - array passed ByRef, Ultima - 2D arrays supported, reworked function (no longer needs temporary array; faster when deleting from end)
; Remarks .......: If the array has one element left (or one row for 2D arrays), it will be set to "" after _ArrayDelete() is used on it.
; Related .......: _ArrayAdd, _ArrayInsert, _ArrayPop, _ArrayPush
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================
Func ___ArrayDelete(ByRef $avArray, $iElement)
If Not IsArray($avArray) Then Return SetError(1, 0, 0)

Local $iUBound = UBound($avArray, 1) - 1

If Not $iUBound Then
	$avArray = ""
	Return 0
EndIf

; Bounds checking
If $iElement < 0 Then $iElement = 0
If $iElement > $iUBound Then $iElement = $iUBound

; Move items after $iElement up by 1
Switch UBound($avArray, 0)
	Case 1
		For $i = $iElement To $iUBound - 1
			$avArray[$i] = $avArray[$i + 1]
		Next
		ReDim $avArray[$iUBound]
	Case 2
		Local $iSubMax = UBound($avArray, 2) - 1
		For $i = $iElement To $iUBound - 1
			For $j = 0 To $iSubMax
				$avArray[$i][$j] = $avArray[$i + 1][$j]
			Next
		Next
		ReDim $avArray[$iUBound][$iSubMax + 1]
	Case Else
		Return SetError(3, 0, 0)
EndSwitch

Return $iUBound
EndFunc   ;==>___ArrayDelete
[/HIDE-THANKS]

 
Status
Not open for further replies.
Back
Top