Jump to content
Jefrey

TCPClient UDF (multi client, event-based, able to bind console app to socket)

Recommended Posts

Hi!

If you liked my TCPServer UDF, you'll also like this one.

Following the same principles, this TCPClient UDF helps you on handling multiple connections to different servers, and set actions depending on two events: OnReceive and OnDisconnect.

It is also multi server (you can connect to many servers at once) and you can also bind a Console-based executable to the socket (similar to -e parameter in NetCat). This feature is useful if you want to use some Console UDF to create a TCP application and don't want to deal with the TCP* functions. Also, it runs on background just firing events, it won't pause your script while waiting/receiving data, so you can do anything else (close and open connections, allow the user to click buttons or just wait on an infinite loop) that your callbacks will be called once the event is fired

It is also very easy to use. See this examples:

Example #1: Connecting to a basic server

By running this (as soon as you open a basic server with Netcat) you will receive a message box telling you when the server closes the connection (the socket ID and his IP address are passed as parameter to your callback function) and also when the server sends something over the TCP socket (the data sent is passed as parameter).

#cs
    Download netcat at https://eternallybored.org/misc/netcat/
    Execute this script
    Run in CMD:
    nc -vv -l -p 8081
#ce

#include "TCPClient.au3"

; First we set the callback functions for the two events (none of them is mandatory)
_TCPClient_OnDisconnect("disconnect")
_TCPClient_OnReceive("received")

; And a parameter
_TCPClient_DebugMode(True)

; Finally we connect to the server at port 8081 at any interface
_TCPClient_Connect('127.0.0.1', 8081)

Func disconnect($iSocket, $sIP)
    MsgBox(0, "Server disconnected", "Server " & $sIP & " disconnected from socket " & $iSocket)
EndFunc   ;==>disconnect

Func received($iSocket, $sIP, $sData, $sPar)
    MsgBox(0, "Data received from " & $sIP, $sData & @CRLF & "Parameter: " & $sPar)
    _TCPClient_Send($iSocket, "You wrote: " & $sData)
    _TCPClient_SetParam($iSocket, 'will write again')
EndFunc   ;==>received

While 1
    Sleep(100)
WEnd

Example #2: Requesting a page from a HTTP server

In this example, we run this code and it will get the response from a HTTP server. Of course, as we are requesting google.com index, it may just show a redirect page to a local (with country top-level domain) Google page or with some stuff on the URL.

#include "TCPClient.au3"

_TCPClient_OnReceive("received")

_TCPClient_DebugMode(True)

$iSocket = _TCPClient_Connect(TCPNameToIP('google.com'), 80)

If @error Then Exit

_TCPClient_Send($iSocket, "GET / HTTP/1.0" & @CRLF & @CRLF)


Func received($iSocket, $sIP, $sData, $sParam)

    MsgBox(0, "Data received", $sData)
    _TCPClient_Disconnect($iSocket)

EndFunc   ;==>received

While 1
    Sleep(100)
WEnd

Example #3: Command prompt bound to the socket after password requesting

By running this example, we will be asked for a password, which is 123456 as we set on the script. If the password is correct, we will see the Command Prompt live-updated (try running a ping to some server, for example).

#include "TCPClient.au3"

#cs
    To test this example,
    execute a netcat server,
    running this commands:
    nc -vv -l -p 31337
#ce

Global $Password = "123456"

_TCPClient_OnReceive("receive")
_TCPClient_OnDisconnect("disconnect")

_TCPClient_DebugMode()

Func receive($iSocket, $sIP, $sData, $mPar)
    If $mPar = "login" Then
        If $sData = $Password Then
            ; right password, let's change the parameter
            _TCPClient_SetParam($iSocket, "logged")

            ; and now bind
            _TCPClient_BindAppToSocket($iSocket, "cmd.exe")

        Else
            _TCPClient_Send($iSocket, "Wrong password. Try again: ")
        EndIf
    Else
        If $sData = "exit" Then
            ; unbinds
            _TCPClient_UnBindAppToSocket($iSocket)

            ; says bye
            _TCPClient_Send($iSocket, "See you")

            ; closes connection
            _TCPClient_Disconnect($iSocket)
        Else
            ; sends command directly to the process
            _TCPClient_SendToBound($iSocket, $sData)
        EndIf
    EndIf
EndFunc

Func disconnect($iSocket, $sIP)
    MsgBox(0, $iSocket, $sIP)
EndFunc

$iSocket = _TCPClient_Connect('127.0.0.1', '31337')

If @error Then
    MsgBox(0, "", "could not connect. Error: " & @error)
    Exit
EndIf

; Sets parameter to login, so we know what the server is doing
_TCPClient_SetParam($iSocket, "login")

_TCPClient_Send($iSocket, "Please enter password: ")

While True
    Sleep(100)
WEnd

The limit is your imagination? Well, maybe.

Functions list:

  • _TCPClient_Connect($sSvr, $iPort)
    _TCPClient_Disconnect($iSocket)
    _TCPClient_SetParam($iSocket, $sPar)
    _TCPClient_Send($iSocket, $sData)
    _TCPClient_Broadcast($sData [, $iExceptSocket = 0 ])
    _TCPClient_ListConnections()
    _TCPClient_BindAppToSocket($iSocket, $sCommand [, $sWorkingDir = @WorkingDir ])
    _TCPClient_SendToBound($iSocket, $sData)
    _TCPClient_UnBindAppToSocket($iSocket)
    _TCPClient_OnReceive($sCallback)
    _TCPClient_OnDisconnect($sCallback)
    _TCPClient_DebugMode([ $bMOde = "toggle" ])
    _TCPClient_AutoTrim([ $bMode = "toggle" ])
    _TCPClient_SocketToConnID($iSocket)
    _TCPClient_ConnIDToSocket($iConn)
    _TCPClient_SocketToIP($iSocket)

Help file and more examples included!

Latest version: 1.0.0

Download: https://www.autoitscript.com/forum/files/file/377-tcpclient-udf/

Changelog

  • 1.0.0 - First release - 03/12/2015

If you can't open the help file, please uncompress it, go to properties and click Unlock.

Fork me on Github: http://github.com/jesobreira/tcpclient-udf 

Edited by Jefrey

My stuff

Spoiler

My UDFs  _AuThread multithreading emulation for AutoIt · _ExtInputBox an inputbox with multiple inputs and more features · forceUTF8 fix strings encoding without knowing its original charset · JSONgen JSON generator · _TCPServer UDF multi-client and multi-task (run on background) event-based TCP server easy to do · _TCPClient_UDF multi-server and multi-task (runs on background) event-based TCP client easy to do · ParseURL and ParseStr functions ported from PHP · _CmdLine UDF easily parse command line parameters, keys or flags · AutoPHP Create documents (bills, incomes) from HTML by sending variables/arrays from AutoIt to PHP · (Un)Serialize Convert arrays and data into a storable string (PHP compatible) · RTTL Plays and exports to MP3 Nokia-format monophonic ringtones (for very old cellphones) · I18n library Simple and easy to use localization library · Scripting.Dictionary OOP and OOP-like approach · Buffer/stack limit arrays to N items by removing the last one once the limit is reached · NGBioAPI UDF to work with Nitgen fingerprint readers · Serial/Licensing system require license key based on unique machine ID from your users · HTTP a simple WinHTTP library that allows GET, POST and file uploads · Thread true AutoIt threads (under-dev) · RC4 RC4 encryption compatible with PHP and JS ·  storage.au3 localStorage and sessionStorage for AutoIt Classes _WKHtmlToX uses wkhtmlto* to convert HTML files and webpages into PDF or images (jpg, bmp, gif, png...) Snippets _Word_DocFindReplaceByLongText replace strings using Word UDF with strings longer than 255 characters (MSWord limit) rangeparser parser for printing-like pages interval (e.g.: "1,2,3-5") EnvParser parse strings/paths with environment variables and get full path Random stuff Super Mario beep sound your ears will hurt

 

Share this post


Link to post
Share on other sites

HI Jefrey and thanks for sharing this UDF
Currently I'm at the beginning on experimenting stuff,


looking in to "example list clients.au3"
I need some basic example on how to make the server respond when it\I needs to send an HTML (a linked form) to the a clients browsers request
Then finally when the form is submitted, the form will post back some data to the server which is what I want to eventually post\send back to the client script
Can you give an example how it can be started off using "example list clients.au3"

TIA

Share this post


Link to post
Share on other sites

Hi, @Deye!

Actually what you are trying to do is to create a HTTP server. Note that this UDF supports TCP protocol in a generic state. This means that while you can of course create a HTTP server with it, you will not find everything ready to use as it just takes care about the network part.

Sending the form is as easy as: https://github.com/jesobreira/TCPServerUDF/blob/master/example HTTP Server.au3#L20 (notice the HTML on the lines 20-23).

However for parsing the user request as well as form data, you will need to handle and parse the HTTP headers sent by the browser. It's not something so hard to understand, but depending on what you want to offer, it's a bite of work. Basically it's just string parsing, nothing that you won't solve with a few StringSplit()s, comparisons and regexp - but a lot of them.

If you want to create a full-featured webserver (good luck!), I suggest you to read the HTTP specs: https://www.w3.org/Protocols/Specs.html

If what you want is something simple, I suggest you to use Chrome Dev Tools (Ctrl + Shift + J), go to "Network" tab and get familiarized with the HTTP headers sent and received by the browser. You'll see that it's not hard at all. Using a sniffer (Smartsniff or Socketsniff, or even Wireshark although it might be too advanced for simple analysis) against your browser is also very learningful; you can see how the headers and HTML are sent.

If you need any further help feel free to comment on this thread!


My stuff

Spoiler

My UDFs  _AuThread multithreading emulation for AutoIt · _ExtInputBox an inputbox with multiple inputs and more features · forceUTF8 fix strings encoding without knowing its original charset · JSONgen JSON generator · _TCPServer UDF multi-client and multi-task (run on background) event-based TCP server easy to do · _TCPClient_UDF multi-server and multi-task (runs on background) event-based TCP client easy to do · ParseURL and ParseStr functions ported from PHP · _CmdLine UDF easily parse command line parameters, keys or flags · AutoPHP Create documents (bills, incomes) from HTML by sending variables/arrays from AutoIt to PHP · (Un)Serialize Convert arrays and data into a storable string (PHP compatible) · RTTL Plays and exports to MP3 Nokia-format monophonic ringtones (for very old cellphones) · I18n library Simple and easy to use localization library · Scripting.Dictionary OOP and OOP-like approach · Buffer/stack limit arrays to N items by removing the last one once the limit is reached · NGBioAPI UDF to work with Nitgen fingerprint readers · Serial/Licensing system require license key based on unique machine ID from your users · HTTP a simple WinHTTP library that allows GET, POST and file uploads · Thread true AutoIt threads (under-dev) · RC4 RC4 encryption compatible with PHP and JS ·  storage.au3 localStorage and sessionStorage for AutoIt Classes _WKHtmlToX uses wkhtmlto* to convert HTML files and webpages into PDF or images (jpg, bmp, gif, png...) Snippets _Word_DocFindReplaceByLongText replace strings using Word UDF with strings longer than 255 characters (MSWord limit) rangeparser parser for printing-like pages interval (e.g.: "1,2,3-5") EnvParser parse strings/paths with environment variables and get full path Random stuff Super Mario beep sound your ears will hurt

 

Share this post


Link to post
Share on other sites

Thank you Jefrey,

I was looking for something simple as possible
All I'm wishing to do is host a linked form (not mine) with a webhook addressed to http://MyScriptTCPListener.ddns.net:55555 that is to send me the submitted form's filled data

The linked form (embedded style) contains 
index.html -> file
css        -> folder
js         -> folder

The problem thing left for me is to reveal the sent data sent from the form's webhook tool
https://www.autoitscript.com/forum/topic/189648-content-type-multipart/

I was told that it can be done with having the webhook directed to a simple php script
But I'm not sure how, if its possible to direct the server listener script to the php script file (While when using TCPListen())

However I'd still prefer having the data revealed with autoit code

Thanks
 

Edited by Deye

Share this post


Link to post
Share on other sites

Hi @Deye,

As I said this is a TCP Server library, not a HTTP Server library (HTTP is a specified protocol inside TCP). With this library you can create servers of virtually any protocol, although of course you must follow the specs of the creators of the protocol you want to recreate (or even create your own protocol). Depending on the protocol specs, it can demand more or less work.

I've wrote a simple example of form data getting using just this library, easy to adapt to your needs. However when developing any kind of server of any protocol, be 100% sure you're able to code it on a secure way (hackers do exist and are around).

#cs
    Run this script
    Point your browser to http://localhost:8081/
#ce

#include "TCPServer.au3"

_TCPServer_OnReceive("received")

_TCPServer_DebugMode(True)
_TCPServer_SetMaxClients(10)

_TCPServer_Start(8081)


Func received($iSocket, $sIP, $sData, $sParam)
    $sMethod = StringLeft($sData, StringInStr($sData, " ")-1) ; the first header comes in the format: GET / HTTP/1.1 or POST / HTTP/1.1
    $sFile = StringLeft($sData, StringInStr($sData, " ", 2)) ; this is to get the file (after the method - /) - we will not use on this sample but it is useful

    If $sMethod = "GET" Then
        _TCPServer_Send($iSocket, "HTTP/1.0 200 OK" & @CRLF & _         ; HTTP headers
                        "Content-Type: text/html" & @CRLF & @CRLF & _   ; plus 2 line breaks
                        "<h1>Form example</h1>" & @CRLF & _             ; then HTML code
                        "<form method=""post"">" & @CRLF & _
                        "<input type=""text"" name=""test"" placeholder=""Type something"" />" & @CRLF & _
                        "<input type=""number"" name=""somenumber"" placeholder=""Number"" />" & @CRLF & _
                        "<input type=""submit"">" & @CRLF & _
                        "</form>")

        ; you could even send a file:
        #cs
        _TCPServer_Send($iSocket, "HTTP/1.0 200 OK" & @CRLF & _         ; HTTP headers
                        "Content-Type: text/html" & @CRLF & @CRLF & _   ; plus 2 line breaks
                        FileRead("yourfile.html"))
        #ce

        _TCPServer_Close($iSocket)

    ElseIf $sMethod = "POST" Then
        ; the form data is at the last line of the request data, URL encoded
        $sFormdata = StringSplit($sData, @CRLF)
        $sFormdata = $sFormdata[$sFormdata[0]] ; get last line

        ; parse the data
        $aData = ParseStr($sFormdata)

        ; sends some headers plus 2 line breaks as http specs says
        ; (browsers understand 2 line breaks as the separation between headers and HTML code)
        _TCPServer_Send($iSocket, "HTTP/1.0 200 OK" & @CRLF & _         ; HTTP headers
                        "Content-Type: text/html" & @CRLF & @CRLF)  ; plus 2 line breaks

        ; sends some HTML code
        _TCPServer_Send($iSocket, "<!DOCTYPE html>" & @CRLF)
        _TCPServer_Send($iSocket, "<html>" & @CRLF)
        _TCPServer_Send($iSocket, "<body>" & @CRLF)
        _TCPServer_Send($iSocket, "<h1>Form data</h1>" & @CRLF)
        _TCPServer_Send($iSocket, "<ul>" & @CRLF)
        ; shows user data on the page
        For $i = 1 To $aData[0][0]
            ; protects against XSS vulnerability
            $sKey = htmlspecialchars($aData[$i][0])
            $sValue = htmlspecialchars($aData[$i][1])

            _TCPServer_Send($iSocket, "<li><b>" & $sKey & ":</b> " & $sValue & "</li>" & @CRLF)
        Next

        ; ends sending html
        _TCPServer_Send($iSocket, "<a href=""/"">Go back</a>" & @CRLF)
        _TCPServer_Send($iSocket, "</body>" & @CRLF)
        _TCPServer_Send($iSocket, "</html>")

        ; closes socket
        _TCPServer_Close($iSocket)
    EndIf
EndFunc   ;==>received

While 1
    Sleep(100)
WEnd

; =========== internal use only ==============

#cs
    @author Jefrey
    @link https://www.autoitscript.com/forum/topic/188052-phps-parse_url-and-parse_str-ported-to-autoit3/
#ce
Func ParseStr($sStr)
    Local $aExplode = StringSplit($sStr, "&"),$aExplode2
    Local $aResult[$aExplode[0]+1][2]
    For $i = 1 To $aExplode[0]
        $aExplode2 = StringSplit($aExplode[$i], "=")
        $aResult[$i][0] = $aExplode2[1]
        $aResult[$i][1] = $aExplode2[2]

        ; URL decode
        $aResult[$i][1] = StringReplace($aResult[$i][1], "+", " ")
        Local $matches = StringRegExp($aResult[$i][1], "\%([abcdefABCDEF0-9]{2})", 3)
        If IsArray($matches) Then
            For $match In $matches
                $aResult[$i][1] = StringReplace($aResult[$i][1], "%" & $match, BinaryToString('0x' & $match))
            Next
        EndIf
    Next
    $aResult[0][0] = $aExplode[0]
    Return $aResult
EndFunc

#cs
    @author Jefrey
    very basic work based on php.net/htmlspecialchars
#ce

Func htmlspecialchars($sStr)
    $sStr = StringReplace($sStr, '&', '&amp;')
    $sStr = StringReplace($sStr, '"', '&quot;')
    $sStr = StringReplace($sStr, "'", "&apos;")
    $sStr = StringReplace($sStr, "<", "&lt;")
    $sStr = StringReplace($sStr, ">", "&gt;")
    Return $sStr
EndFunc

 


My stuff

Spoiler

My UDFs  _AuThread multithreading emulation for AutoIt · _ExtInputBox an inputbox with multiple inputs and more features · forceUTF8 fix strings encoding without knowing its original charset · JSONgen JSON generator · _TCPServer UDF multi-client and multi-task (run on background) event-based TCP server easy to do · _TCPClient_UDF multi-server and multi-task (runs on background) event-based TCP client easy to do · ParseURL and ParseStr functions ported from PHP · _CmdLine UDF easily parse command line parameters, keys or flags · AutoPHP Create documents (bills, incomes) from HTML by sending variables/arrays from AutoIt to PHP · (Un)Serialize Convert arrays and data into a storable string (PHP compatible) · RTTL Plays and exports to MP3 Nokia-format monophonic ringtones (for very old cellphones) · I18n library Simple and easy to use localization library · Scripting.Dictionary OOP and OOP-like approach · Buffer/stack limit arrays to N items by removing the last one once the limit is reached · NGBioAPI UDF to work with Nitgen fingerprint readers · Serial/Licensing system require license key based on unique machine ID from your users · HTTP a simple WinHTTP library that allows GET, POST and file uploads · Thread true AutoIt threads (under-dev) · RC4 RC4 encryption compatible with PHP and JS ·  storage.au3 localStorage and sessionStorage for AutoIt Classes _WKHtmlToX uses wkhtmlto* to convert HTML files and webpages into PDF or images (jpg, bmp, gif, png...) Snippets _Word_DocFindReplaceByLongText replace strings using Word UDF with strings longer than 255 characters (MSWord limit) rangeparser parser for printing-like pages interval (e.g.: "1,2,3-5") EnvParser parse strings/paths with environment variables and get full path Random stuff Super Mario beep sound your ears will hurt

 

Share this post


Link to post
Share on other sites

Sorry I couldn't get back to this earlier, something came up and had to be away
I see now that the page that might be holding the data is transferred to a another thank you (URL) page ..

anyways .., right now I'm a bit out of it, I will need to wait till I can better understand the step by step flow of the process and in overall to try and get a better picture of how all this needs to be worked out  ..

Thanks again 

Edit: Thanks again for the example! , finally got it worked out.. Your help saved me from a lot of trouble :sweating: :thumbsup:

 

Edited by Deye

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

  • Similar Content

    • By tarretarretarre
      Autoit-Socket-IO
      Introduction
      Autoit-Socket-IO is a event driven TCP/IP wrapper heavily inspired from Socket.IO with focus on user friendliness and long term sustainability.
      I created this UDF because I was fascinated how Socket.IO made a such scary task "reliable and secure networking" so simple for the developer. So this was my main motivation.
      I constantly want to make this UDF faster and better, so if you have any suggestions. Do not hesitate to make requests!
      Features
      Flexiable and easy to understand API Above avarage documentation "Fully featured" examples Security in form of data encryption and middleware-support Limitations
      Speed. Because I want this UDF to be as flexible and simple as possible. Sometimes speed is sacrificed, but that does not mean i don't try to . It is not possible to emit objects mainly because autoit does not support serialization. Only 1D-arrays can be emitted (2D arrays will probably never be supported) Success story
      Since December 2017-now I have used version 1.5.0 in an production environment for 40+ clients with great success, the only downtime is planned windows updates and power outages.
      Getting started
      Download the script from AutoIt or pull it from the official github repo git@github.com:tarreislam/Autoit-Socket-IO.git and checkout the tag 2.0.0 The documentation is located at Docs\index.html Take a look in the examples/ folder Changelog
      Version 2.0.0 (This update break scripts. Please consult the upgrade.md for guidance)
      All global internal variables has been renamed. Added a bunch of new API methods: _Io_RegisterMiddleware, _Io_whoAmI, _Io_IsClient, _Io_IsServer, _Io_getAllByProperty and _Io_getFirstByProperty and some more. Read more about these in the documentation. _Io_socketGetProperty now has a setter method called _Io_socketSetProperty which can be used to set custom properties. _Io_socketGetProperty now has a third parameter "default" which is used when a property is not found Removed _Io_setEventPostScript and _Io_setEventPretScript in favor of _Io_RegisterMiddleware Improved documentation (It still needs some love though) Improved the verbosity of _Io_DevDebug  
      Newest version (2019-09-29!)
      Autoit-Socket-IO-2.0.0.zip
      Older versions (Not supported anymore)
      Autoit-Socket-IO-1.0.0.zip Autoit-Socket-IO-1.1.0.zip Autoit-Socket-IO-1.3.0.zip Autoit-Socket-IO-1.4.0.zip Autoit-Socket-IO-1.5.0.zip
    • By AoRaToS
      I started working on this program in the summer of 2008 then I stopped cause I faced some problems I couldn't overcome back then. Now that I've practiced more and have become a better scripter/programmer I'm releasing the program to the public to get some opinions. I know it's not a new concept but it's the first program I started besides some small stuff I did just for practice! I won't post the source code yet because it's still under construction, although I'm sure I've posted early stages of the code with bugs in the past in some topic...
      What I wanted was a simple, small, serverless program that would work without installation cause I wanted it for where I work, so I ended up with this!
      I have attached some images of various versions, also visit the forum thread.
      The package includes s!mpL3 LAN Messenger and the full change log.
      Current version 2.9.9.1! [04/07/2019]
      Check the Change Log below!
       
       
      http://www.autoitscript.com/forum/index.php?showtopic=88782
       
       
       
      Read the license before using this software.
       
    • By Colduction
      Hello Guys and AutoIt Scriptwriters!🎉❤️
      I've created a script to notify to me if RDP main IP changed then send a message via Telegram bot to me
      But some of my RDP's Main IP are @IPAddress1 or @IPAddress3 or Public IP Address...
      I want to detect automatically the IP that windows client can run RDP to remotely control
      This image can help you that what i say, there are three RDP with specified IP, i want to run script in these RDP's then capture those IP's changes then notify me via Telegram bot

    • By rudi
      Hello,
      When new versions e.g. of your compiled script cannot be replaced on the server, as they are in use, you can use this script to manage to close the open handles and to replace the old file with your new version.

      ; Autoit v3.3.14.5 #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Description=Close OpenFileHandlles, replace file on Server with a new version #AutoIt3Wrapper_Res_Fileversion=1 #AutoIt3Wrapper_Res_LegalCopyright=(c) 2019 by Rudolf Thilo, IT-Beratung Rudolf Thilo #AutoIt3Wrapper_Res_SaveSource=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <NetShare.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <EditConstants.au3> ; Enumerate open files on the server $DragDropOpenFile = "<drag-drop file locked on Server to be closed and replaced>" $DragDropNewFile = "<drag-drop file to replace the one on the server>" $NewFile = "" $Gui_h = 250 $Gui_w = 800 $vDist = 7 ; GUICreate($GuiTitle, $w, $h, @DesktopWidth - $w - 100, @DesktopHeight - $h - 60, -1, $WS_EX_ACCEPTFILES) ; generally enable drag-drop for files into other GUI controls $myGui = GUICreate("force close of all NETWORK opened file handles", $Gui_w, $Gui_h, 100, 100, -1, $WS_EX_ACCEPTFILES) $InputFileToClose = GUICtrlCreateInput($DragDropOpenFile, 20, $vDist, $Gui_w - 40, 20) GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; allow drag-droping files for this control, $InputFile Opt("Guicoordmode", 2) $InputFileNew = GUICtrlCreateInput($DragDropNewFile, -1, $vDist) GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; allow drag-droping files for this control, $InputFile GUICtrlSetState(-1, $GUI_DISABLE) $lServer = GUICtrlCreateLabel("<server>", -1, $vDist) $lShare = GUICtrlCreateLabel("<share>", -1, $vDist) $lPath = GUICtrlCreateLabel("<path>", -1, $vDist) $lFile = GUICtrlCreateLabel("<file>", -1, $vDist) $doit = GUICtrlCreateButton("search for and close open file handles", -1, $vDist) GUICtrlSetState(-1, $GUI_DISABLE) $exit = GUICtrlCreateButton("cancel", -1, $vDist) GUISetState() $FN = False $FNnew = "" $FNmatch = False $ToolTitle = "" $ToolTxt = "" While 1 $input = GUICtrlRead($InputFileToClose) If $input <> $DragDropOpenFile Then ; da wurde was reingezogen $DragDropOpenFile = $input If StringLeft($input, 2) = "\\" Then $Type = "UNC" $ServerShareUNC = StringLeft($input, StringInStr($input, "\", 0, 4) - 1) $fRelPathFN = StringReplace($input, $ServerShareUNC, "") $fPath = StringLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1)) $FN = StringTrimLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1)) ElseIf StringMid($input, 2, 1) = ":" Then ; Pfad mit Laufwerksbuchstabe, evtl. Netzwerk Mapping (erforderlich) $drive = StringLeft($input, 2) $Type = DriveGetType($drive) If $Type = "Network" Then $ServerShareUNC = DriveMapGet($drive) $foo = StringReplace($input, $drive, $ServerShareUNC) ; Laufwerkspfad in UNC Pfad umwandeln $fRelPathFN = StringReplace($foo, $ServerShareUNC, "") $fPath = StringLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1)) $FN = StringTrimLeft($fRelPathFN, StringInStr($fRelPathFN, "\", 0, -1)) Else MsgBox(0, @ScriptLineNumber, "This script can *ONLY* close open file handles on NETWORK SHARES!" & @CRLF & _ $input & @CRLF & _ $drive & " = " & $Type) ContinueLoop 2 EndIf EndIf $Server = StringLeft($ServerShareUNC, StringInStr($ServerShareUNC, "\", 0, 3) - 1) $Share = StringTrimLeft($ServerShareUNC, StringInStr($ServerShareUNC, "\", 0, 3) - 1) GUICtrlSetData($lServer, $Server) GUICtrlSetData($lShare, $Share) GUICtrlSetData($lPath, $fPath) GUICtrlSetData($lFile, $FN) GUICtrlSetState($doit, $GUI_ENABLE) GUICtrlSetState($InputFileNew, $GUI_ENABLE) EndIf If $NewFile <> GUICtrlRead($InputFileNew) Then $NewFile = GUICtrlRead($InputFileNew) If $NewFile <> $DragDropNewFile Then If StringInStr($NewFile, $DragDropNewFile) Then $NewFile = StringReplace($NewFile, $DragDropNewFile, "") GUICtrlSetData($InputFileNew, $NewFile) EndIf $FNnew = StringTrimLeft($NewFile, StringInStr($NewFile, "\", 0, -1)) If $FN = $FNnew Then If $FNmatch = False Then $FNmatch = True GUICtrlSetData($doit, "Search for open file handles, close them, overwrite old file.") EndIf Else If $FNmatch Then $FNmatch = False GUICtrlSetData($doit, "Search for open file handles and close them.") GUICtrlSetData($InputFileNew,$DragDropNewFile) EndIf EndIf EndIf EndIf Switch GUIGetMsg() Case $exit, $GUI_EVENT_CLOSE GUIDelete($myGui) Exit Case $doit AbArbeiten($Server, $Share, $fPath, $FN) EndSwitch WEnd Func AbArbeiten($_Srv, $_Shr, $_fPth, $_fNme) Local $iID = 0 Local $iRights = 1 Local $iLckCount = 2 Local $iFPFN = 3 Local $iUser = 4 ConsoleWrite($_fPth & $_fNme & @CRLF) Local $aFile = _Net_Share_FileEnum($_Srv) If IsArray($aFile) Then ; _ArrayDisplay($aFile) Local $x $ToolTxt = "Open Handles:" $ToolTitle = $aFile[0][0] & " handles still waiting to be checkt..." UpdateToolTip() AdlibRegister(UpdateToolTip, 1000) For $x = $aFile[0][0] To 1 Step -1 $ToolTitle = $x & " handles waiting to be checked..." If Not StringInStr($aFile[$x][$iFPFN], $_fPth & $_fNme) Then ; ConsoleWrite("Nix Enthalten in: " & $aFile[$x][$iFPFN] & @CRLF) _ArrayDelete($aFile, $x) Else $ToolTxt &= @CRLF & $aFile[$x][$iFPFN] & ", User = " & $aFile[$x][$iUser] ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ToolTxt = ' & $ToolTxt & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console EndIf Next $aFile[0][0] = UBound($aFile) - 1 _ArraySort($aFile, 0, 1, 0, $iUser) ; _ArrayDisplay($aFile, $aFile[0][0] & " FileLocks found.") If $aFile[0][0] = 0 Then $ToolTitle = "Done. No open handles coud be found." $ToolTxt &= @CRLF & "Nothing to be closed!" Sleep(2000) $ToolTxt = "" Else $ToolTitle = $aFile[0][0] & " Handles found to be closed..." $CloseErr = 0 For $x = 1 To $aFile[0][0] If _Net_Share_FileClose($Server, $aFile[$x][$iID]) Then $ToolTxt &= @CRLF & @TAB & "Handle closed: " & $aFile[$x][$iID] Else $ToolTxt &= @CRLF & "ERROR: Handle Close Failed! --> " & $aFile[$x][$iFPFN] & ", User = " & $aFile[$x][$iUser] $CloseErr += 1 EndIf Next ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $CloseErr = ' & $CloseErr & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console If $CloseErr = 0 Then $ToolTitle = "Alle open handles were closed successfully." If FileExists($NewFile) Then If FileCopy($NewFile, $input, 1 + 8) Then $ToolTitle = "File could be replaced." $ToolTxt = "done" Else $ToolTitle = "File could *NOT* be replaced" $ToolTxt = "Most propably a newly open file handle was created while this script was running." & @CRLF & _ "Just start over again." EndIf EndIf Else $ToolTitle = $CloseErr & " handles could *NOT* be closed!" Sleep(2000) EndIf Sleep(1000) $ToolTxt = "" $ToolTitle = "" EndIf Else MsgBox(0, "not an array", $aFile & @CRLF & @error & @CRLF & @extended) EndIf EndFunc ;==>AbArbeiten Func UpdateToolTip() ToolTip($ToolTxt, MouseGetPos(0) + 20, MouseGetPos(1) + 20, $ToolTitle) ; ConsoleWrite( $ToolTxt & @CRLF & $ToolTitle & @CRLF & "-------------------" & @CRLF) EndFunc ;==>UpdateToolTip Rudi.
    • By HansHenrik
      ----------
      edit: this is probably in the wrong place, can a moderator move it to wherever it belongs?
      ----------

      is there any way to completely disable TCPTimeout and make TCPRecv() wait indefinitely? maybe setting it to 0 or -1 or something? 
      the docs doesn't seem to mention any way to disable it

      - the underlying C code would set SO_RCVTIMEO to 0 , aka

      DWORD timeout=0;
      setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
×
×
  • Create New...