Jump to content
AlexFing17

How Server can connect to client over the internet with tcp

Recommended Posts

i am trying to figure out how a server can connect to a client Over the internet. 

In this is script. The client connects to the server on the same machine (localhost) and executes the commands from the client.

How can I change that instead communicating over localhost to communicate over the internet with tcp ipaddress and a port.

 

What i actually need help of is

1. The server will open a port and  listen to communication from a No-ip address

2. I input the no-ip address and correct port in the client side, and when i click on connect, it connects to the server if its online

 

 

This is the client

#include <GuiConstantsEx.au3>
THIS IS THE CLIENT

#include <NamedPipes.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

; ===============================================================================================================================
; Description ...: This is the client side of the pipe demo
; Author ........: Paul Campbell (PaulIA)
; Notes .........:
; ===============================================================================================================================

; ===============================================================================================================================
; Global constants
; ===============================================================================================================================

Global Const $BUFSIZE = 4096
Global Const $DEFCMD = "cmd.exe /c dir c:\"
Global Const $PIPE_NAME = "\\$\\pipe\\AutoIt3"
Global Const $ERROR_MORE_DATA = 234

; ===============================================================================================================================
; Global variables
; ===============================================================================================================================

Global $g_idEdit, $g_idMemo, $g_idSend, $g_idServer, $g_hPipe

; ===============================================================================================================================
; Main
; ===============================================================================================================================

CreateGUI()
MsgLoop()

; ===============================================================================================================================
; Creates a GUI for the client
; ===============================================================================================================================
Func CreateGUI()
    Local $hGUI = GUICreate("FarC0nn3c7", 500, 400, -1, -1, $WS_SIZEBOX)
    GUICtrlCreateLabel("Server:", 2, 14, 52, 20, $SS_RIGHT)
    $g_idServer = GUICtrlCreateEdit("<local>", 56, 10, 200, 20, $SS_LEFT)
    GUICtrlCreateLabel("Command:", 2, 36, 52, 20, $SS_RIGHT)
    $g_idEdit = GUICtrlCreateEdit($DEFCMD, 56, 32, 370, 20, $SS_LEFT)
    $g_idSend = GUICtrlCreateButton("Pawn Dem", 430, 32, 60, 20)
    $g_idMemo = GUICtrlCreateEdit("", 0, 62, _WinAPI_GetClientWidth($hGUI), 332)
    GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New")
    GUISetState()
EndFunc   ;==>CreateGUI

; ===============================================================================================================================
; Logs an error message to the display
; ===============================================================================================================================
Func LogError($sMessage)
    $sMessage &= " (" & _WinAPI_GetLastErrorMessage() & ")"
    GUICtrlSetData($g_idMemo, GUICtrlRead($g_idMemo) & $sMessage & @CRLF)
EndFunc   ;==>LogError

; ===============================================================================================================================
; Logs a message to the display
; ===============================================================================================================================
Func LogMsg($sMessage)
    GUICtrlSetData($g_idMemo, GUICtrlRead($g_idMemo) & $sMessage & @CRLF)
EndFunc   ;==>LogMsg

; ===============================================================================================================================
; MsgLoop
; ===============================================================================================================================
Func MsgLoop()
    While True
        Switch GUIGetMsg()
            Case $g_idSend
                SendCmd()
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
EndFunc   ;==>MsgLoop

; ===============================================================================================================================
; This function opens a pipe to the server
; ===============================================================================================================================
Func OpenPipe()
    Local $sName, $sPipe
    ; Get pipe handle
    $sName = GUICtrlRead($g_idServer)
    If $sName = "<local>" Then $sName = "."
    $sPipe = StringReplace($PIPE_NAME, "$", $sName)
    $g_hPipe = _WinAPI_CreateFile($sPipe, 2, 6)
    If $g_hPipe <> -1 Then Return True
    LogError("OpenPipe failed")
    Return False
EndFunc   ;==>OpenPipe

; ===============================================================================================================================
; This function reads a message from the pipe
; ===============================================================================================================================
Func ReadMsg()
    Local $bSuccess, $iRead, $pBuffer, $tBuffer

    $tBuffer = DllStructCreate("char Text[4096]")
    $pBuffer = DllStructGetPtr($tBuffer)
    GUICtrlSetData($g_idMemo, "")
    While 1
        $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, 0)
        If $iRead = 0 Then ExitLoop
        If Not $bSuccess Or (_WinAPI_GetLastError() = $ERROR_MORE_DATA) Then ExitLoop
        GUICtrlSetData($g_idMemo, StringLeft(DllStructGetData($tBuffer, "Text"), $iRead), 1)
    WEnd
EndFunc   ;==>ReadMsg

; ===============================================================================================================================
; This function sends a command to the server
; ===============================================================================================================================
Func SendCmd()
    If OpenPipe() Then
        SetReadMode()
        WriteMsg(GUICtrlRead($g_idEdit))
        ReadMsg()
        _WinAPI_CloseHandle($g_hPipe)
    EndIf
EndFunc   ;==>SendCmd

; ===============================================================================================================================
; This function sets the pipe read mode
; ===============================================================================================================================
Func SetReadMode()
    If Not _NamedPipes_SetNamedPipeHandleState($g_hPipe, 1, 0, 0, 0) Then
        LogError("SetReadMode: _NamedPipes_SetNamedPipeHandleState failed")
    EndIf
EndFunc   ;==>SetReadMode

; ===============================================================================================================================
; This function writes a message to the pipe
; ===============================================================================================================================
Func WriteMsg($sMessage)
    Local $iWritten, $iBuffer, $pBuffer, $tBuffer

    $iBuffer = StringLen($sMessage) + 1
    $tBuffer = DllStructCreate("char Text[" & $iBuffer & "]")
    $pBuffer = DllStructGetPtr($tBuffer)
    DllStructSetData($tBuffer, "Text", $sMessage)
    If Not _WinAPI_WriteFile($g_hPipe, $pBuffer, $iBuffer, $iWritten, 0) Then
        LogError("WriteMsg: _WinAPI_WriteFile failed")
    EndIf
EndFunc   ;==>WriteMsg
Spoiler

 

 

And this is the server

#include <GuiConstantsEx.au3>
#include <NamedPipes.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#NoTrayIcon
; ===============================================================================================================================
; Description ...: This is the server side of the pipe demo
; Author ........: Paul Campbell (PaulIA)
; Notes .........:
; ===============================================================================================================================

; ===============================================================================================================================
; Global constants
; ===============================================================================================================================

Global Const $DEBUGGING = False
Global Const $BUFSIZE = 4096
Global Const $PIPE_NAME = "\\.\\pipe\\AutoIt3"
Global Const $TIMEOUT = 5000
Global Const $WAIT_TIMEOUT = 258
Global Const $ERROR_IO_PENDING = 997
Global Const $ERROR_PIPE_CONNECTED = 535

; ===============================================================================================================================
; Global variables
; ===============================================================================================================================

Global $g_hEvent, $g_idMemo, $g_pOverlap, $g_tOverlap, $g_hPipe, $g_hReadPipe, $g_iState, $g_iToWrite

; ===============================================================================================================================
; Main
; ===============================================================================================================================

CreateGUI()
InitPipe()
MsgLoop()

; ===============================================================================================================================
; Creates a GUI for the server
; ===============================================================================================================================
Func CreateGUI()

    Local $hGUI

    $hGUI = GUICreate("Pipe Server", 500, 400, -1, -1, $WS_SIZEBOX)
    $g_idMemo = GUICtrlCreateEdit("", 0, 0, _WinAPI_GetClientWidth($hGUI), _WinAPI_GetClientHeight($hGUI))
    GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New")
    GUISetState()
EndFunc   ;==>CreateGUI

; ===============================================================================================================================
; This function creates an instance of a named pipe
; ===============================================================================================================================
Func InitPipe()
    ; Create an event object for the instance
    $g_tOverlap = DllStructCreate($tagOVERLAPPED)
    $g_pOverlap = DllStructGetPtr($g_tOverlap)
    $g_hEvent = _WinAPI_CreateEvent()
    If $g_hEvent = 0 Then
        LogError("InitPipe ..........: API_CreateEvent failed")
        Return
    EndIf
    DllStructSetData($g_tOverlap, "hEvent", $g_hEvent)

    ; Create a named pipe
    $g_hPipe = _NamedPipes_CreateNamedPipe($PIPE_NAME, _ ; Pipe name
            2, _ ; The pipe is bi-directional
            2, _ ; Overlapped mode is enabled
            0, _ ; No security ACL flags
            1, _ ; Data is written to the pipe as a stream of messages
            1, _ ; Data is read from the pipe as a stream of messages
            0, _ ; Blocking mode is enabled
            1, _ ; Maximum number of instances
            $BUFSIZE, _ ; Output buffer size
            $BUFSIZE, _ ; Input buffer size
            $TIMEOUT, _ ; Client time out
            0) ; Default security attributes
    If $g_hPipe = -1 Then
        LogError("InitPipe ..........: _NamedPipes_CreateNamedPipe failed")
    Else
        ; Connect pipe instance to client
        ConnectClient()
    EndIf
EndFunc   ;==>InitPipe

; ===============================================================================================================================
; This function loops waiting for a connection event or the GUI to close
; ===============================================================================================================================
Func MsgLoop()
    Local $iEvent

    Do
        $iEvent = _WinAPI_WaitForSingleObject($g_hEvent, 0)
        If $iEvent < 0 Then
            LogError("MsgLoop ...........: _WinAPI_WaitForSingleObject failed")
            Exit
        EndIf
        If $iEvent = $WAIT_TIMEOUT Then ContinueLoop
        Debug("MsgLoop ...........: Instance signaled")

        Switch $g_iState
            Case 0
                CheckConnect()
            Case 1
                ReadRequest()
            Case 2
                CheckPending()
            Case 3
                RelayOutput()
        EndSwitch
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
EndFunc   ;==>MsgLoop

; ===============================================================================================================================
; Checks to see if the pending client connection has finished
; ===============================================================================================================================
Func CheckConnect()
    Local $iBytes

    ; Was the operation successful?
    If Not _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iBytes, False) Then
        LogError("CheckConnect ......: Connection failed")
        ReconnectClient()
    Else

        $g_iState = 1
    EndIf
EndFunc   ;==>CheckConnect

; ===============================================================================================================================
; This function reads a request message from the client
; ===============================================================================================================================
Func ReadRequest()
    Local $pBuffer, $tBuffer, $iRead, $bSuccess

    $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]")
    $pBuffer = DllStructGetPtr($tBuffer)
    $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, $g_pOverlap)

    If $bSuccess And ($iRead <> 0) Then
        ; The read operation completed successfully
        Debug("ReadRequest .......: Read success")
    Else
        ; Wait for read Buffer to complete
        If Not _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iRead, True) Then
            LogError("ReadRequest .......: _WinAPI_GetOverlappedResult failed")
            ReconnectClient()
            Return
        Else
            ; Read the command from the pipe
            $bSuccess = _WinAPI_ReadFile($g_hPipe, $pBuffer, $BUFSIZE, $iRead, $g_pOverlap)
            If Not $bSuccess Or ($iRead = 0) Then
                LogError("ReadRequest .......: _WinAPI_ReadFile failed")
                ReconnectClient()
                Return
            EndIf
        EndIf
    EndIf

    ; Execute the console command
    If Not ExecuteCmd(DllStructGetData($tBuffer, "Text")) Then
        ReconnectClient()
        Return
    EndIf

    ; Relay console output back to the client
    $g_iState = 3
EndFunc   ;==>ReadRequest

; ===============================================================================================================================
; This function relays the console output back to the client
; ===============================================================================================================================
Func CheckPending()
    Local $bSuccess, $iWritten

    $bSuccess = _WinAPI_GetOverlappedResult($g_hPipe, $g_pOverlap, $iWritten, False)
    If Not $bSuccess Or ($iWritten <> $g_iToWrite) Then
        Debug("CheckPending ......: Write reconnecting")
        ReconnectClient()
    Else
        Debug("CheckPending ......: Write complete")
        $g_iState = 3
    EndIf
EndFunc   ;==>CheckPending

; ===============================================================================================================================
; This function relays the console output back to the client
; ===============================================================================================================================
Func RelayOutput()
    Local $pBuffer, $tBuffer, $sLine, $iRead, $bSuccess, $iWritten

    $tBuffer = DllStructCreate("char Text[" & $BUFSIZE & "]")
    $pBuffer = DllStructGetPtr($tBuffer)
    ; Read data from console pipe
    _WinAPI_ReadFile($g_hReadPipe, $pBuffer, $BUFSIZE, $iRead)
    If $iRead = 0 Then
        LogMsg("RelayOutput .......: Write done")
        _WinAPI_CloseHandle($g_hReadPipe)
        _WinAPI_FlushFileBuffers($g_hPipe)
        ReconnectClient()
        Return
    EndIf

    ; Get the data and strip out the extra carriage returns
    $sLine = StringLeft(DllStructGetData($tBuffer, "Text"), $iRead)
    $sLine = StringReplace($sLine, @CR & @CR, @CR)
    $g_iToWrite = StringLen($sLine)
    DllStructSetData($tBuffer, "Text", $sLine)
    ; Relay the data back to the client
    $bSuccess = _WinAPI_WriteFile($g_hPipe, $pBuffer, $g_iToWrite, $iWritten, $g_pOverlap)
    If $bSuccess And ($iWritten = $g_iToWrite) Then
        Debug("RelayOutput .......: Write success")
    Else
        If Not $bSuccess And (_WinAPI_GetLastError() = $ERROR_IO_PENDING) Then
            Debug("RelayOutput .......: Write pending")
            $g_iState = 2
        Else
            ; An error occurred, disconnect from the client
            LogError("RelayOutput .......: Write failed")
            ReconnectClient()
        EndIf
    EndIf
EndFunc   ;==>RelayOutput

; ===============================================================================================================================
; This function is called to start an overlapped connection operation
; ===============================================================================================================================
Func ConnectClient()
    $g_iState = 0
    ; Start an overlapped connection
    If _NamedPipes_ConnectNamedPipe($g_hPipe, $g_pOverlap) Then
        LogError("ConnectClient .....: ConnectNamedPipe 1 failed")
    Else
        Switch @error
            ; The overlapped connection is in progress
            Case $ERROR_IO_PENDING
                Debug("ConnectClient .....: Pending")
                ; Client is already connected, so signal an event
            Case $ERROR_PIPE_CONNECTED
                LogMsg("ConnectClient .....: Connected")
                $g_iState = 1
                If Not _WinAPI_SetEvent(DllStructGetData($g_tOverlap, "hEvent")) Then
                    LogError("ConnectClient .....: SetEvent failed")
                EndIf
                ; Error occurred during the connection event
            Case Else
                LogError("ConnectClient .....: ConnectNamedPipe 2 failed")
        EndSwitch
    EndIf
EndFunc   ;==>ConnectClient

; ===============================================================================================================================
; Dumps debug information to the screen
; ===============================================================================================================================
Func Debug($sMessage)
    If $DEBUGGING Then LogMsg($sMessage)
EndFunc   ;==>Debug

; ===============================================================================================================================
; Executes a command and returns the results
; ===============================================================================================================================
Func ExecuteCmd($sCmd)
    Local $tProcess, $tSecurity, $tStartup, $hWritePipe

    ; Set up security attributes
    $tSecurity = DllStructCreate($tagSECURITY_ATTRIBUTES)
    DllStructSetData($tSecurity, "Length", DllStructGetSize($tSecurity))
    DllStructSetData($tSecurity, "InheritHandle", True)

    ; Create a pipe for the child process's STDOUT
    If Not _NamedPipes_CreatePipe($g_hReadPipe, $hWritePipe, $tSecurity) Then
        LogError("ExecuteCmd ........: _NamedPipes_CreatePipe failed")
        Return False
    EndIf

    ; Create child process
    $tProcess = DllStructCreate($tagPROCESS_INFORMATION)
    $tStartup = DllStructCreate($tagSTARTUPINFO)
    DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup))
    DllStructSetData($tStartup, "Flags", BitOR($STARTF_USESTDHANDLES, $STARTF_USESHOWWINDOW))
    DllStructSetData($tStartup, "StdOutput", $hWritePipe)
    DllStructSetData($tStartup, "StdError", $hWritePipe)
    If Not _WinAPI_CreateProcess("", $sCmd, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) Then
        LogError("ExecuteCmd ........: _WinAPI_CreateProcess failed")
        _WinAPI_CloseHandle($g_hReadPipe)
        _WinAPI_CloseHandle($hWritePipe)
        Return False
    EndIf
    _WinAPI_CloseHandle(DllStructGetData($tProcess, "hProcess"))
    _WinAPI_CloseHandle(DllStructGetData($tProcess, "hThread"))

    ; Close the write end of the pipe so that we can read from the read end
    _WinAPI_CloseHandle($hWritePipe)

    LogMsg("ExecuteCommand ....: " & $sCmd)
    Return True
EndFunc   ;==>ExecuteCmd

; ===============================================================================================================================
; Logs an error message to the display
; ===============================================================================================================================
Func LogError($sMessage)
    $sMessage &= " (" & _WinAPI_GetLastErrorMessage() & ")"
    ConsoleWrite($sMessage & @LF)
EndFunc   ;==>LogError


; ===============================================================================================================================
; This function is called when an error occurs or when the client closes its handle to the pipe
; ===============================================================================================================================
Func ReconnectClient()
    ; Disconnect the pipe instance
    If Not _NamedPipes_DisconnectNamedPipe($g_hPipe) Then
        LogError("ReconnectClient ...: DisonnectNamedPipe failed")
        Return
    EndIf

    ; Connect to a new client
    ConnectClient()
EndFunc   ;==>ReconnectClient

 

Share this post


Link to post
Share on other sites

So, the major issue here is going to be whether or not the server IP and port are in fact internet accessible.  Is the "server" in the cloud/accessible from the internet as far as you know?  If the "server" sits behind a firewall (i.e. via business or home ISP), the firewall will need to be configured to pass traffic to the server (i.e. port forwarding/triggering, DMZ, etc.)


Share this post


Link to post
Share on other sites
10 hours ago, spudw2k said:

So, the major issue here is going to be whether or not the server IP and port are in fact internet accessible.  Is the "server" in the cloud/accessible from the internet as far as you know?  If the "server" sits behind a firewall (i.e. via business or home ISP), the firewall will need to be configured to pass traffic to the server (i.e. port forwarding/triggering, DMZ, etc.)

i will configure it to allow it since is my own computer but in my second home.

 

my problem here  is how i can make them connect to each other and receive the commands. 

since the code i posted only allow localhost connection. 

How can i connect from the client to the server with an external ip of the computer the server is installed on.

 

Thank you

Share this post


Link to post
Share on other sites
4 hours ago, RTFC said:

Look into  "port forwarding"

My problem is how i can make my client connect to the server with the external ip of the computer the server is running on.

 

Thank you

Share this post


Link to post
Share on other sites

Well, you mentioned No-Ip, so you would/could use that to tie your external IP to a Domain Name (URL).   Then it's just a matter of configuring your home router/firewall to do either port forwarding or triggering.

Instead of the period "." (denotes local), you should be able to replace it with an IP or resolvable hostname (Domain Name).

 


Share this post


Link to post
Share on other sites
On 4/19/2017 at 4:06 PM, spudw2k said:

Well, you mentioned No-Ip, so you would/could use that to tie your external IP to a Domain Name (URL).   Then it's just a matter of configuring your home router/firewall to do either port forwarding or triggering.

Instead of the period "." (denotes local), you should be able to replace it with an IP or resolvable hostname (Domain Name).

 

I want the server to receive connection from only my no ip adrees..

in a the case where

 

1. if the server is running then it waits for remote connection from my no ip address.

2. so i set the no ip address on my computer and runs the client , the server on my home computer will connect back to it automatic if is online.

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...