
viroman
Members-
Posts
6 -
Joined
-
Last visited
viroman's Achievements

Seeker (1/7)
2
Reputation
-
Viszna reacted to a post in a topic: Base64 utf8 decoder without external dependencies
-
MarcusD reacted to a post in a topic: Base64 utf8 decoder without external dependencies
-
Hello, just looked around and googled for a proper way to decode base64 utf8 encoded strings and did not find good examples. So created own. Additionally includes base64 utf8 encoder. Possibly some one finds it useful. Used https://www.base64encode.org/ to encode base64-utf8 Global $b64 = StringSplit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", "", 2); Func _getBase64Num($a) $a = Asc($a) If $a > 47 And $a < 58 Then Return $a + 4; ElseIf $a > 64 And $a < 91 Then Return $a - 65; ElseIf $a > 96 And $a < 123 Then Return $a - 71; ElseIf $a = 43 Then Return 62 ElseIf $a = 47 Then Return 63 Else Return 64 EndIf EndFunc Func _base64dec_arr($r) While StringCompare(StringLeft($r, 1), " ", 1) = 0 $r = StringMid($r, 2) WEnd Local $a, $d, $t, $c, $n, $o, $h, $i, $b = 0, $f = 0; If(StringLen($r) < 1) Then Return $r; Local $rlen = StringLen($r) Local $g = [1] Redim $g[Ceiling($rlen * 0.75)] $r = StringSplit($r, "", 2); While $b < $rlen $c = _getBase64Num($r[$b]) $b = $b + 1; $n = _getBase64Num($r[$b]) $b = $b + 1; $o = _getBase64Num($r[$b]) $b = $b + 1; $h = _getBase64Num($r[$b]) $b = $b + 1; $i = BitOR(BitShift($c, -18), BitShift($n, -12), BitShift($o, -6), $h) $a = BitAND(BitShift($i, 16), 255) $d = BitAND(BitShift($i, 8), 255) $t = BitAND(255, $i) If $o = 64 Then $g[$f] = $a $f = $f + 1; ElseIf $h = 64 Then $g[$f] = $a $f = $f + 1; $g[$f] = $d $f = $f + 1; Else $g[$f] = $a $f = $f + 1; $g[$f] = $d $f = $f + 1; $g[$f] = $t $f = $f + 1; EndIf WEnd If UBound($g) <> $f Then Redim $g[$f] EndIf Return $g; returns array EndFunc; Func _utf8_decode($str_data) ;expects array Local $tmp_arr = "", $i = 0, $c1, $c2, $c3, $strlen = UBound($str_data); While $i < $strlen $c1 = $str_data[$i]; If $c1 < 128 Then $tmp_arr = $tmp_arr & ChrW($c1); $i = $i + 1; ElseIf $c1 > 191 And $c1 < 224 Then $c2 = $str_data[$i + 1]; $tmp_arr = $tmp_arr & ChrW(BitOR(BitShift(BitAND($c1, 31), -6), BitAND($c2, 63))); $i = $i + 2; Else $c2 = $str_data[$i + 1]; $c3 = $str_data[$i + 2]; $tmp_arr = $tmp_arr & ChrW(BitOR(BitShift(BitAND($c1, 15), -12), BitShift(BitAND($c2, 63), -6), BitAND($c3, 63))); $i = $i + 3; EndIf WEnd Return $tmp_arr; EndFunc; Func _base64_utf8_dec($a) Return _utf8_decode(_base64dec_arr($a)) EndFunc Func _utf8_base64_enc($a) Return _base64_enc(_utf8_encode($a)) EndFunc Func _utf8_encode($stringOr) Local $utftext = "", $start = 0, $end = 0, $n = 0, $c1, $enc; Local $string = StringSplit($stringOr, "", 2); Local $stringl = UBound($string) While $n < $stringl $c1 = AscW($string[$n]) If $c1 > 127 Then If $c1 < 2048 Then $enc = ChrW(BitOR(BitShift($c1, 6), 192)) & ChrW(BitOR(BitAND($c1, 63), 128)) Else $enc = ChrW(BitOR(BitShift($c1, 12), 224)) & ChrW(BitOR(BitAND(BitShift($c1, 6), 63), 128)) & ChrW(BitOR(BitAND($c1, 63), 128)) EndIf If $end > $start Then $utftext = $utftext & StringMid($stringOr, $start + 1, $end - $start) EndIf $utftext = $utftext & $enc; $n = $n + 1; $start = $n; Else $n = $n + 1; EndIf $end = $n; WEnd If $end > $start Then $utftext = $utftext & StringMid($stringOr, $start + 1, $stringl - $start) EndIf Return $utftext; EndFunc; Func _base64_enc($rOr) Local $e, $t, $h, $o, $d = 0, $b = ""; Local $r = StringSplit($rOr, "", 2); Local $rL = UBound($r) While $d < $rL $e = AscW($r[$d]) $d = $d + 1; If $d < $rL Then $t = AscW($r[$d]) Else $t = 0; EndIf $d = $d + 1; If $d < $rL Then $h = AscW($r[$d]) Else $h = 0; EndIf $d = $d + 1; $o = BitOR(BitShift($e, -16), BitShift($t, -8), $h) $b = $b & $b64[BitAND(BitShift($o, 18), 63)] & $b64[BitAND(BitShift($o, 12), 63)] & $b64[BitAND(BitShift($o, 6), 63)] & $b64[BitAND(63, $o)] WEnd $rL = Mod($rL, 3); If $rL = 1 Then $b = StringLeft($b, StringLen($b) - 2) & "=="; ElseIf $rL = 2 Then $b = StringLeft($b, StringLen($b) - 1) & "="; EndIf Return $b EndFunc; MsgBox(0, _utf8_base64_enc("your string"), _base64_utf8_dec("eW91ciBzdHJpbmc=")); base64_dec_enc_utf8.au3
-
Hello, I have noticed the biggest problem actually on chinese system, in my case Windows 8.. I use Autoit script for upload files in html form via CGI as compiled binary. It works fine on all systems except chinese (possibly broken on all asian OSs) If I use standard command ConsoleRead(); the readed output is broken, so some chars differ but at least the file size is correct (on english, german, french etc. systems the readed output is OK despite of binary or text form of the uploaded file) if I use ConsoleRead(False, True) thenn the problem is, the file size is smaller than expected and output is broken, so this mode does not help to fix it, (and again on english, german, french etc. systems the readed output is OK when used binary reading) I tried to use different switches when compiling script to exe, like /ansi or /unicode, but problem was unsolved. I tried then other programs for cgi upload, as example written in C, and voila, there it worked fine with upload on chinese win8 system, so my assumption was, there is some bug when reading console stdout on chinese system. My question is, is that possible to use other techniques to read stdout rather than to use ConsoleRead()? May be windows native implementations? Does someone have the solution for that problem in Autoit (to save the redeveloping time)
-
Nope, nothing works, the error seems to be very deeply, also forget the code above.. 2 Kip, i have reversed your code little bit and you have choosen wrong way to go that in reality doesn't let you to use many simultaneous connections, only one conenction works fine, snd any others do not work.. Why? Because you are registering with GUIRegisterMsg the message IDs from the number of actual connections(computed by size) beginning by 1024(0x0400) Let say, i have connected with the client and got 1025 ID ( 1024 + 1 ) because array has 1 element Then i have again connected with the client and got 1026 ID ( 1024 + 2 ) because array has 2 elements than again new connection 1027 ID ( 1024 + 3 ) because array has 3 elements and so on... You are computing always array size and add it to 1024 or however.. New connection means new array element.. It may be ok, if no one server/client disconnects, but as soon one is disconnecting, you begin to produce errornous handling. Why??? By taking example above, let say, 1025,1026,1027, also 3 elements, and now ID 1025 disconnects or connection get lost... now we have 2 elements in our array, because you are deleting it... What do we have now? We have IDs 1026, 1027, also two elements, now new client will connect... We add again 1024 plus size of array, also two, 1024 + 2 = 1026 (so as you do it in your code) Now what do we do, if we are doing it so???? We overwrite also ID 1026 with the socket of new connection so that event from old connection on old ID 1026 will never be called again, but only new event for new conenction. So, now i try to forget about computing array size and let them just increase the number of messages as soon GUIRegisterMsg is called. Well, may be it get rid of such errors, but i am poor programmer, therefore not sure, if i do it correctly
-
May be someone will need it quick and dirty _TCP_RegisterEventServer _TCP_RegisterEventClient From now on i use these commands separately to register events for client and server, else it wasn't working before. #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.0.0 Author: Kip Script Function: TCP UDF v3 #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #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_RegisterEventServer($hSocket, $iEvent, $sFunction) _TCP_RegisterEventClient($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 Global $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] Global $__TCP_SOCKETSc[1][7]; //added for separat client ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Create ; Description ...: Initializes the server. ; Syntax.........: _TCP_Server_Create($iPort, $sIP="0.0.0.0") ; Parameters ....: $iPort - The port number the server should listen to. ; $sIP - IP address. (Default = "0.0.0.0") ; Return values .: The socket handle. ; Author ........: Kip ; Modified.......: ; Remarks .......: Only 1 server can be created per script. ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Create($iPort, $sIP="0.0.0.0") Local $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 Func ___TCP_OnAccept($hWnd, $iMsgID, $WParam, $LParam) Local $hSocket = $WParam Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $hClient, $uBound Abs($hWnd) ; Stupid AU3Check... 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 ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Client_Stop ; Description ...: Stops the client. ; Syntax.........: _TCP_Client_Stop($hSocket) ; Parameters ....: $hSocket - Client socket. ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: The client socket is the return value of _TCP_Client_Create(). ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Client_Stop($hSocket) Local $iElement, $i $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETSc)-1 If $__TCP_SOCKETSc[$i][0] = $hSocket Then $iElement = $i ExitLoop EndIf Next If $iElement Then ___ASockShutdown($__TCP_SOCKETSc[$iElement][0]) TCPCloseSocket($__TCP_SOCKETSc[$iElement][0]) ___ArrayDelete($__TCP_SOCKETSc, $iElement) Return True EndIf Return False EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Stop ; Description ...: Stops the server, and closes all client connections. ; Syntax.........: _TCP_Server_Stop() ; Parameters ....: ; Return values .: True ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Stop() Local $i ___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 True EndFunc Func ___TCP_Server_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam ) Local $hSocket = $WParam Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $sDataBuff, $iElement, $i Abs($hWnd) $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 $sDataBuff = TCPRecv($hSocket, 1024) Call($__TCP_SOCKETS[0][2], $hSocket, $sDataBuff, $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 ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_DisconnectClient ; Description ...: Disconnects a client of the server. ; Syntax.........: _TCP_Server_DisconnectClient($hSocket) ; Parameters ....: $hSocket - Client socket. ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: The client socket is the $hSocket parameter of a _TCP_RegisterEvent callback function. ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_DisconnectClient($hSocket) Local $iElement, $i $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 True EndIf Return False EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_ClientList ; Description ...: Returns the sockets of all connected clients. ; Syntax.........: _TCP_Server_ClientList() ; Parameters ....: ; Return values .: An 1 dimensional array of all connected clients. ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_ClientList() Local $aReturn[1], $i 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 ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_Broadcast ; Description ...: Sends data to all connected clients. ; Syntax.........: _TCP_Server_Broadcast($sData) ; Parameters ....: $sData - The data to send. ; Return values .: True ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Server_Broadcast($sData) Local $i For $i = 1 to UBound($__TCP_SOCKETS)-1 If $__TCP_SOCKETS[$i][0] Then TCPSend($__TCP_SOCKETS[$i][0], $sData) Next Return True EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Client_Create ; Description ...: Creates a new client. ; Syntax.........: _TCP_Client_Create($sIP , $iPort) ; Parameters ....: $sIP - The IP address to connect to. ; $iPort - Port on which the created socket will be connected. ; Return values .: Client socket handle. ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Client_Create($sIP , $iPort) ReDim $__TCP_SOCKETSc[UBound($__TCP_SOCKETSc)+1][7] local $hSocket = ___ASocket() $__TCP_SOCKETSc[UBound($__TCP_SOCKETSc)-1][0] = $hSocket $__TCP_SOCKETSc[UBound($__TCP_SOCKETSc)-1][1] = 0x0400 + (UBound($__TCP_SOCKETSc)-1) ___ASockSelect( $hSocket, $__TCP_WINDOW, 0x0400 + (UBound($__TCP_SOCKETSc)-1), BitOR( $FD_READ, $FD_WRITE, $FD_CONNECT, $FD_CLOSE ) ) GUIRegisterMsg( 0x0400 + (UBound($__TCP_SOCKETSc)-1), "___TCP_Client_OnSocketEvent" ) ___ASockConnect( $hSocket, $sIP, $iPort ) Return $hSocket EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_RegisterEvent ; Description ...: Registers an event. ; Syntax.........: _TCP_RegisterEvent($hSocket, $iEvent, $sFunction) ; Parameters ....: $hSocket - Socket of the server or a client. ; $iEvent - Event number. It can be any these values: ; * $TCP_SEND ; * $TCP_RECEIVE ; * $TCP_CONNECT => Client only ; * $TCP_DISCONNECT ; * $TCP_NEWCLIENT => Server only ; Return values .: Success - True ; Failure - False ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_RegisterEventServer($hSocket, $iEvent, $sFunction) Local $iSelected = 0 Local $i 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 False EndSwitch Return True EndFunc ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Server_ClientIP ; Description ...: Converts a client socket handle to IP address. ; Syntax.........: _TCP_Server_ClientIP($hSocket) ; Parameters ....: $hSocket - Client socket handle. ; Return values .: A string with the IP address. ; Author ........: Unknown ; Modified.......: Kip ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== 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 ; #FUNCTION# ;=============================================================================== ; ; Name...........: _TCP_Send ; Description ...: Sends data to a server or client. ; Syntax.........: _TCP_Send($hSocket, $sText) ; Parameters ....: $hSocket - Client or server socket handle. ; $sText - Data to send. ; Return values .: ; Author ........: Kip ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........; ; Example .......; ; ; ;========================================================================================== Func _TCP_Send($hSocket, $sText) Return TCPSend($hSocket, $sText) EndFunc Func ___TCP_Client_OnSocketEvent( $hWnd, $iMsgID, $WParam, $LParam ) Local $iError = ___HiWord( $LParam ) Local $iEvent = ___LoWord( $LParam ) Local $hSocket, $iElement, $i, $sDataBuff Abs($hWnd) Abs($WParam) $hSocket = 0 $iElement = 0 For $i = 1 to UBound($__TCP_SOCKETSc)-1 If $__TCP_SOCKETSc[$i][1] = $iMsgID Then $hSocket = $__TCP_SOCKETSc[$i][0] $iElement = $i ExitLoop EndIf Next If $hSocket Then Switch $iEvent Case $FD_READ; Data has arrived! $sDataBuff = TCPRecv( $hSocket, 1024) Call($__TCP_SOCKETSc[$i][2], $hSocket, $sDataBuff, $iError) $sDataBuff = "" Case $FD_WRITE Call($__TCP_SOCKETSc[$i][3], $hSocket, $iError) Case $FD_CONNECT Call($__TCP_SOCKETSc[$i][4], $hSocket, $iError) Case $FD_CLOSE ___ASockShutdown( $hSocket ) TCPCloseSocket( $hSocket ) Call($__TCP_SOCKETSc[$i][5], $hSocket, $iError) ___ArrayDelete($__TCP_SOCKETSc, $iElement) EndSwitch EndIf EndFunc Func _TCP_RegisterEventClient($hSocket, $iEvent, $sFunction) Local $iSelected = 0 Local $i If $__TCP_SOCKETSc[0][0] Then $iSelected = 0 Else For $i = 0 to UBound($__TCP_SOCKETSc)-1 If $__TCP_SOCKETSc[$i][0] = $hSocket Then $iSelected = $i ExitLoop EndIf Next If Not $iSelected Then Return 0 EndIf Switch $iEvent Case $TCP_SEND $__TCP_SOCKETSc[$iSelected][3] = $sFunction Case $TCP_RECEIVE $__TCP_SOCKETSc[$iSelected][2] = $sFunction Case $TCP_CONNECT $__TCP_SOCKETSc[$iSelected][4] = $sFunction Case $TCP_DISCONNECT $__TCP_SOCKETSc[$iSelected][5] = $sFunction Case $TCP_NEWCLIENT $__TCP_SOCKETSc[$iSelected][6] = $sFunction Case Else Return False EndSwitch Return True EndFunc ;================================================================================================================== ; ; 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 <cephas at clergy dot net> ; Modified.......: Jos van der Zande <jdeb at autoitscript dot com> - 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
-
I wanted to post my quick and dirty method, i have copied the file TCP.au3 to TCPc.au3, so that c on the end stays for client version, and than i have renamed all functions and variables on same way, with c on the end, and then i have only commented out ;TCPStartup() in TCPc.au3 and than in my main file i have included them on the beginning #include "TCP.au3" #include "TCPc.au3" And renamed all clients calls like so $hClient = _TCP_Client_Createc("62.153.159.92", 80); Create the client. Which will connect to the local ip address on port 88 ConsoleWrite('->Client handler created!' & @CRLF) ;Debug, for fun :P _TCP_RegisterEventc($hClient, $TCP_RECEIVEc, "Received"); Function "Received" will get called when something is received _TCP_RegisterEventc($hClient, $TCP_CONNECTc, "Connected"); And func "Connected" will get called when the client is connected. _TCP_RegisterEventc($hClient, $TCP_DISCONNECTc, "Disconnected"); And "Disconnected" will get called when the server disconnects us, or when the connection is lost. Now server gets created and clients too.. Quick and dirty, i know, takes 15 minutes, but saves all other troubles.. Now may be you know, how to fix them on your way.
-
Hello Kip, thank you very much for your work. I wanted to create something like port forwarder with your library, but i got some problems. Also, i need server and client connections in same script to do that.. and the connection to forwarded remote host can not be established after server was firstly started, at least not as event. Why does that happen? Is it possible to create connection sockets after server was started? In this example the function "Connected" doesn't get called if hServer gets created, also $hServer = _TCP_Server_Create(88); Of course, if i uncomment it, it works, but not working is not what i need Why does that happen, how to fix? Thanky you! #include "TCP.au3" $hServer = _TCP_Server_Create(88); ;Comment hServer and it works then? Why? ;_TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClientLocal"); ;_TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "DisconnectedLocal"); ;_TCP_RegisterEvent($hServer, $TCP_RECEIVE, "ReceivedLocal"); $hClient = _TCP_Client_Create("62.153.159.92", 80) ConsoleWrite('->Client handler created!' & @CRLF) _TCP_RegisterEvent($hClient, $TCP_RECEIVE, "Received") _TCP_RegisterEvent($hClient, $TCP_CONNECT, "Connected") _TCP_RegisterEvent($hClient, $TCP_DISCONNECT, "Disconnected") While 1 Sleep(1000) WEnd Func Connected($hSocket, $iError); If not $iError Then; If there is no error... ConsoleWrite('->Client connected!' & @CRLF) ;Debug, for fun :P Else; ,else... ConsoleWrite('->Client not connected!' & @CRLF) ;Debug, for fun :P EndIf EndFunc Func Received($hSocket, $sReceived, $iError) ToolTip("CLIENT: We received this: "& $sReceived, 10,10) EndFunc Func Disconnected($hSocket, $iError) ConsoleWrite('->Client; connection closed or lost!' & @CRLF) EndFunc