Jump to content
Sign in to follow this  

Find and eliminate memory leaks

Recommended Posts


Hi. I'm a teacher and I do a lot of tutorials and other presentations on my computer. I've developed a tool using AutoIt and Adobe AIR to display all the shortcuts I use while I'm presenting. According to the forum rules this would mean that I've developed a keylogger, so I can't show any of the code, but I'm still hoping someone will help me solve an issue I'm having - a memory leak (or at least I think that's it).

I can see the application is taking up more and more memory, but it never goes super crazy. I think it was at 25 MB at one point and that was it. However I see that the longer the application is running less responsive it is. It doesn't capture all the events, or it simply lags. 

I'm using AssocArrays and _MouseOnEvent UDFs, _WinAPI_SetTimer, _WinAPI_SetWindowsHookEx, _Singleton and TCP. I've done some research before posting this and I know there are some issues in special cases, but all solutions were "code specific". Since I can't post any of the code I couldn't respond in those threads. Other than that it really doesn't seem to be the problem with any of the UDFs, so my question is:

Is this a memory leak? If so how can I find it and remove it? What to do to avoid it in the future.

I understand that declaring variables over and over (something in the timer) may be the cause of this, so according to what I've read on the forum I've changed the variables to Global and moved them outside the functions. That way they are only declared once, and then only values are being reassigned. That unfortuantly didn't help. Is there anything else I could do or look for?

BTW - I've used Adobe AIR to create a nice UI. If someone want's to create something similar UEZ was kind enough to share his code of creating such GUI with nice antialiased labels. 


Share this post

Link to post
Share on other sites

A memory leak is when you permanently requesting resources without releasing these resources and the memory consumption for your exe is increasing constantly. A very good tool is ProcessExplorer from MS to find out for memory leaks.

If this applies to your code you have to check for resource consumption without releasing it.

E.g. if you call the function from the link you have posted (_GDIPlus_CreateCurvedTranslucentPanel) without releasing it


you will cause a memory leak.

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post

Link to post
Share on other sites

Thanks for the answer. I do understand the basic concept and I was very careful when coding this. Even without being aware of memory leaks and what causes them I think it's a good programming habit to release resources - even just for clarity, so I am doing it. I fear that maybe there's something in the UDF's that is causing it (if it in fact is a memory leak). Then I notice something strange happening (like this lagging) I did notice that the app is still sending events over TCP at the exact time they should be send (probably because this is WinAPI hook that executes my function when the event happens), however a timer that is supposed to count down from last event is soooo far behind that it never sends the "clear" event (or whatever it is that it's suppose to be doing). When that happens memory consumption is about 25 MB but it never gets any higher. When I run the app fresh it's about 12MB. 

Also, aside from the timer I have a Do Untill WinActive("appname") loop (so that the app doesn't close) which checks is the Adobe AIR app is running, and if it doesn't the main code continues to run, which calls the _closeApp() (which clears resources).

;Wait for KeySnatcher to close or force stop by user
   Until GUIGetMsg() = $GUI_EVENT_CLOSE or Not WinExists($hwndGui)

$hwndGui is a handle to the other app (the GUI made in Adobe AIR). So that then GUI is not running the app should close. The _closeApp() has a Beep function just for debug purposes. When I notice the lagging the app doesn't beep nor it shuts down. 

My intuition tells me there's something wrong with this loop. But what could it be? Could WinExists be the cause?

Below is everything that I can post without going into details of mouse / keyboard hooks. I'm not including any Global variables or other declarations that are above this code. As you can see I try to be as tidy and elegant with my coding to the best of my ability.

; ===========================================================
; Main Code
; ===========================================================

Func _Initialize()

   ;Initialize TCP variables
   $sServer = ""
   $sSocket = 0
   $sPort = 0

   ;Read settings from INI file
   $sPort = IniRead ( @ScriptDir & "\config.ini", "server", "port", "1007" )
   $cHotkey = IniRead ( @ScriptDir & "\config.ini", "control", "hotkey", "Ctrl + Alt + Shift + F12" )
   $hCmd = IniRead ( @ScriptDir & "\config.ini", "server", "hashcmd", "<::cmd>" )
   $iTimeOut = IniRead ( @ScriptDir & "\config.ini", "control", "timeout_ms", "3500" )
   Local $sServerAppTitle = IniRead ( @ScriptDir & "\config.ini", "server", "server_app_title", "KeySnatcher" )

   ;See if there's a KeySnatcher AIR app or another copy of THIS script running
   $hwndGui = WinActivate($sServerAppTitle)
   If $hwndGui = 0 or _Singleton($app, 1) = 0 Then
 ;few beeps
      Exit     ;exit - no resource were set yet, no need to free them

   ;Set all variables to their default state (fresh start)

   ;Try to connect to already running KeySnatcher (AIR) app

   ;Execute the core script

; Establish a TCP connection with AIR server (KeySnatcher)
Func ConnectToAirApp()
   Local $sIPAddress = $sServer
   Local $iPort = $sPort

   $sSocket = TCPConnect($sIPAddress, $iPort)

   If @error Then
      ; The server is probably offline/port is not opened on the server.
      Local $iError = @error
      MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "Connect", "Could not connect, Error code: " & $iError)
      debug("Connection succesful")
EndFunc   ;==>ConnectToAirApp

; Create System Hooks and keep the script alive (infinite loop)
Func _Run()

   ;Creatre system hooks for keyboard and mouse: classes\sysHook.au3

   ; Create a Timer to clear the display buffer after given time
   $iTimerID = _WinAPI_SetTimer(0, 0, $iTimerDelay, DllCallbackGetPtr($hTimerProc))

   ;System hooks created, timer set, ready to go

   ;Wait for KeySnatcher (AIR app) to close or force stop by user
   Until GUIGetMsg() = $GUI_EVENT_CLOSE or Not WinExists($hwndGui)

   ;Close the script

EndFunc   ;==>_run



Share this post

Link to post
Share on other sites

I agree with your intuition.

I would definitely place blame on the UDFs without posting full code for others to examine.

Share this post

Link to post
Share on other sites

How about the loop? Could WinExists cause this? Or maybe it's the fact that I have a Sleep(100) in that loop, and on top of that I have a _WinAPI Timer in my code as well. Maybe they get into some sort of a conflict? 

As for the UDFs - they come from the forum. I've posted what I use. As for _WinAPI functions I basically use examples from the AutoIt manual. All my code is just bunch of snippets working together (as it usually is). It's really hard to pinpoint. When the app is running, but I don't use my computer (so there's nothing to capture, but the timers are working) everything is fine. It can run for 12 hours and everything is fine. But when I'm presenting it takes about an hour for the app to start lagging. 

I've also noticed that when I do something CPU intensive (like presenting image processing or 3D rendering) the app cautpres few events at once, because "it did not manage" to show each action separately and it shows a couple all at once. Which should not happen. I've tripple checked the code. After each captured event, I send it via TCP to display, and after that I'm clearing the variable that holds what the action was, so if the app was unable to follow me in realtime it should at least show the first event that happened or the last, but not all at once. I don't get it. I tried to increase the priority to High with no effect. I am really lost.

Share this post

Link to post
Share on other sites

In such situations it's very useful to use "eliminating method".

Step by step remove suspicious code and watch if bad behaviour still remains.

At the point when bad behaviour dissapear then you know that lastly removed part of code is source of problems.

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
Sign in to follow this  

  • Similar Content

    • ur
      By ur
      I have used _Singleton function in my script to restrict only one instance to run.
      For testing, I have written below code, and triggered multiple instances.
      #include <Misc.au3> MsgBox(0,"",@ScriptName) if _Singleton(@ScriptName, 1) = 0 Then Msgbox(64, @ScriptName, "The program is already running.") Exit Else MsgBox(0,@ScriptName,"No other instances running") EndIf But all are going to else block.
      Please suggest.
    • n3wbie
      By n3wbie
      i Tried Using Function _single ton
      It Works Like Charm on same computer
      But it is unable to catch up when 2 instance of exe are launched in lan pc
      I would also like to know if there was a way to make particular number of instance work like allow 4-5 instance of same exe to run
    • ahha
      By ahha
      I'm basically processing text files where I'm reading them from a disk file into an input array, going through the input array and skipping what I don't want and writing it out to an output array and then writing the output array to a disk file.  I encountered an "Error allocating memory" message.  I have stripped down the program to illustrate how the memory usage grows in a looping routine (__ReadFiles).  I have tried a _ReduceMemory routine (from https://www.autoitscript.com/forum/topic/134831-is-there-a-way-to-free-up-memory-being-used/ ) and it helps somewhat, however the peak working set continues to grow regardless.  I believe I'm releasing resources (resetting arrays to 0) and am trying to figure out if the leak is from FileFindNextFile or something else I'm doing.   To illustrate the program creates a subdirectory with 50000 simple text files and then runs showing the growing memory usage, Ctrl+q will pause program.  Rerunning the program uses the already created files so it does not have to be re-created.  Any help appreciated.
      ; use this to debug in console window <--- LOOK #AutoIt3Wrapper_run_debug_mode=Y ;#AutoIt3Wrapper_Run_Debug=off ;#AutoIt3Wrapper_Run_Debug=on #include <Array.au3> #include <File.au3> #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #include <EditConstants.au3> HotKeySet ( "^q", "EndProgram" ) ;v2e - added HotKeySet ( "^q", "EndProgram" ); CTRL+q so can pause/exit script Global $hEdit ;for scrolling text box Global $textarray[1] ;1 element $textarray[0] = 0 ;initial count Global $newtextarray[1] ;1 element $newtextarray[0] = 0 ;initial count Global $dir Global $k ;loop count Global $aMemory ;v1g for use in __ShowMemoryUsage("Location: In FileFindNextFile While 1 loop.") Global $debug = 0 ;0=off, 1=on , 2=deeper, - use debug > 1 to see arrays in Funcs $version = "v1g" ;v1g - we have an Autoit "Error allocating memory" somewhere - printing out WorkingSetSize and PeakWorkingSetSize from ProcessGetStats to try and find it __scrolling_text_box_init("--- Read files ---", 1050, 450) ;__scrolling_text_box_init($title, $width, $height) ;set up box - to display text use: __scrolltext($text) WinMove("--- Read files ---", "", 2000, 300) ;move so can see it - on single screen use 10, 30 on dual screen use 2000, 300 __scrolltext("Starting: " & @CRLF) ;illustrate error using current script directory by creating unique directotry and create file in it and put some text into it ----------- $dir = @ScriptDir ;for iterative testing see if test directory already exists - i.e. only need to build this once $dir = @ScriptDir & "\testdir_xcrgua" ;highly unlikely areadly exists unless this program was already run $str = "" ;null it For $j = 1 to 100 ;put 100 lines in each file $str = $str & $j & @CRLF Next If DirGetSize($dir) = -1 Then DirCreate($dir) ;create directory ;then create and fill it For $i = 1 to 50000 ;brute force (and I know it's slow, however straightforward and only 1 time FileWrite($dir & "\" & $i & ".txt", $str) If $i/1000 = Int($i/1000) Then __scrolltext("Writing test file " & $i & "/50000" & @CRLF) Next EndIf MsgBox(262144, "DEBUG", $dir & " <-- should have 50000 files each with 100 numbered lines 1- 100.") MsgBox(262144, "DEBUG", "Paused.") __scrolltext("Reading files in dir = " & $dir & @CRLF) ;__ShowMemoryUsage("Location: Before file count.") ;v1g $fc = __GetFileCount($dir) ;returns file count in $dir ;__ShowMemoryUsage("Location: After file count.") ;v1g __scrolltext("Number of files in dir = " & $fc & @CRLF) MsgBox(262144, "DEBUG", "Paused.") ;in this we get memory allocation erroroccurs between 25K and 50K on my machine __ReadFiles($dir) MsgBox(262144, "DEBUG", "Paused out of loop.") Exit ;----------------------------------- Functions ----------------------------------- Func __ShowMemoryUsage($title) $aMemory = ProcessGetStats() ; Retrieve memory details about the current process. ; If $aMemory is an array then display the following details about the process. If IsArray($aMemory) Then __scrolltext($title & " " & "WorkingSetSize: " & $aMemory[0] & " PeakWorkingSetSize: " & $aMemory[1] & @CRLF) Else __scrolltext("An error occurred in ProcessGetStats() in Func __ShowMemoryUsage($title).") EndIf EndFunc ;__ShowMemoryUsage($title) Func _ReduceMemory($i_PID = -1) ;from https://www.autoitscript.com/forum/topic/134831-is-there-a-way-to-free-up-memory-being-used/ If $i_PID <> -1 Then Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', False, 'int', $i_PID) Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0]) Else Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1) EndIf Return $ai_Return[0] EndFunc ;==>_ReduceMemory Func __GetFileCount($dir) ;returns number of files in $dir - brute force but only about 50K files/directory ;MsgBox(0, "DEBUG", "$dir = '" & $dir & "'") #AutoIt3Wrapper_Run_Debug=off $fcount = 0 ;init count $search = FileFindFirstFile($dir & "\*.*") If $search = -1 Then ;no files found Return($fcount) ;MsgBox(0, "Error", "No files/directories matched the search pattern") ;Exit EndIf ;okay check number of files While 1 $file = FileFindNextFile($search) If @error Then ExitLoop ;exit loop when there are no more files Else $fcount = $fcount + 1 EndIf WEnd FileClose($search) ;be polite Return($fcount) #AutoIt3Wrapper_Run_Debug=on EndFunc Func __ReadFiles($dir) ;just reading to show memory alloc error Local $x Local $skipline #AutoIt3Wrapper_Run_Debug=off $tfc = __GetFileCount($dir) ;get total file count so we can show progress #AutoIt3Wrapper_Run_Debug=on $cfc = 0 ;init currect file count $search = FileFindFirstFile($dir & "\*.*") ;get search handle If $search = -1 Then ;no files found __scrolltext("Working on file: " & $cfc & "/" & $tfc & @CRLF) Return ;MsgBox(0, "Error", "No files/directories matched the search pattern") ;Exit EndIf ;okay go through the files one by one While 1 ;_ReduceMemory() ;this makes little difference - surprising $file = FileFindNextFile($search) If @error = 1 Then ExitLoop ;exit loop when there are no more to do If @extended = 1 Then $adir = 1 ;we have a directory so note it Else $adir = 0 ;a file EndIf ;MsgBox(4096, "File:", $directory&"\"&$file) $cfc = $cfc + 1 __scrolltext("Working on file: " & $cfc & "/" & $tfc & " " & $file & @CRLF) ;show the filename __ShowMemoryUsage("Location: In FileFindNextFile While 1 loop.") ;v1g ;clear out arrays so we have no artifacts from procesing the prior loop ;from here it looks like resetting it is better https://www.autoitscript.com/forum/topic/110933-solved-how-to-delete-whole-array/ $testarray = 0 $newtextarray = 0 Dim $textarray[1] ;1 element $textarray[0] = 0 ;initial count Dim $newtextarray[1] ;1 element $newtextarray[0] = 0 ;initial count ;bring file into memory for faster processing If $adir = 0 Then ;process file $x = _FileReadToArray($dir & "\" & $file, $textarray) ;bring file into memory for faster processing [0] has $textarray count If $x <> 1 Then MsgBox($MB_TOPMOST + $MB_ICONERROR, "ERROR", "Unable to read file into array. Error = " & $x & " @error = " & @error & " @extended = " & @extended) Exit EndIf If $debug > 0 Then _ArrayDisplay($textarray, "INPUT $textarray") ReDim $newtextarray[$textarray[0] + 1] ;create output array ($newtextarray) of the same size as input array ($textarray) and later ReDim the output array to the correct size $newtextarray[0] = 0 ;set the count of actual entries as $newtextarray is empty but has same size as $textarray If $debug > 0 Then _ArrayDisplay($newtextarray, "Starting $newtextarray") ;now the approach is to write out only lines we want then to file For $i = 1 to $textarray[0] ;process all elements (rows, lines) in input array ;If $debug > 0 Then __scrolltext("$textarray[" & $i & "] = '" & $textarray[$i] & "'" & @CRLF) ;show the line $skipline = 0 ;init value to not skip line ;----------- start stripping out stuff ----------- ;this rountine is not the cause of the memory leak so removed ;------------- If $skipline = 0 Then ;write it out $newtextarray[0] = $newtextarray[0] + 1 ;increase count and point to index where we're going to store it in $newtextarray $newtextarray[$newtextarray[0]] = $textarray[$i] Else ;skip the line EndIf Next $fn = $dir & "\processed-1\" & StringLeft($file, StringLen($file) - 4) & "-1.txt" __scrolltext("Processed file written to: " &$fn & @CRLF) ;show the line ;RECALL written out like an array so 1st entry which corresponds to index [0] has count of rows = lines in the file Else ;its a directory - skip it __scrolltext("NOT processed directory (i.e. skipped) : " & $dir & "\" & $file & @CRLF) ;show the line EndIf WEnd EndFunc ;__CleanFiles($dir) Func __scrolling_text_box_init($title, $width, $height) ;from http://www.autoitscript.com/forum/topic/110948-add-text-to-edit-box-and-scroll-it-down/page__p__971158__hl___guictrledit_scroll__fromsearch__1#entry971158 $hGUI = GUICreate($title, $width, $height) $hEdit = GUICtrlCreateEdit("", 10, 10, $width-20, $height-20, BitOr($GUI_SS_DEFAULT_EDIT, $ES_READONLY)) ;$limit = 9223372036854775807 ;2^63 $limit = 1000000000 ;works $x = GUICtrlSetLimit($hEdit, $limit) ;~ If $x = 0 Then ;~ MsgBox(0, "ERROR", "Limit of " & $limit & " is too large.") ;~ Else ;~ MsgBox(0, "Okay", "Limit of " & $limit & " is okay.") ;~ EndIf ;$hButton = GUICtrlCreateButton("Add", 10, 250, 80, 30) GUISetState() EndFunc Func __scrolltext($text) #AutoIt3Wrapper_Run_Debug=off ;prefix everything with date and time e.g. 2014-02-01 HH:MM:SS $dt = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " $text = $dt & $text GUICtrlSetData($hEdit, $text, 1) #AutoIt3Wrapper_Run_Debug=on EndFunc Func EndProgram() $x = MsgBox($MB_TOPMOST + $MB_YESNO + $MB_ICONWARNING, "Paused", "Do you want to continue?") If $x = $IDNO Then Exit ;exit program Else ;just a pause - so continue EndIf EndFunc  
      04 - Clean files - v1g - test for memory leak v1c.au3
    • TheSaint
      By TheSaint
      This is just a little helpful script, that I started using a month or so ago (one program so far), with this version having a Restore ability added (so now using with two programs of mine, as of tonight).
      You can find other alternatives or similar scripts here, the most recent being - _SingleScript
      guinness also has something much more elaborate, that is well worth checking out - _SingletonHWID.
      Just place the following at the beginning of your script, and adjust where needed and wanted (including Scriptname, variable names and MsgBox magic numbers, etc). Perhaps you should read and use the following - Best coding practices ... unlike my slack hobby programmer self (not always).
      #include <Misc.au3> Global $ans, $exe, $handle, $pid, $script, $Scriptname, $status, $w, $wins ; Assign the program name (window title). $Scriptname = "Update Mp3 Artwork v7.9 (updated December 2015)" ; The following line both sets the unique ID of the current program, plus queries if a program with the same ID is running already. $status = _Singleton("update-mp3artwork-thsaint", 1) If $status = 0 Then ; A program with the same ID is already running. ; Assign a PID for previous script, based on current executable name, whether current script is compiled or not, and assign the executable name. If @Compiled = 1 Then $pid = ProcessExists(@ScriptName) $exe = @ScriptName Else $pid = ProcessExists("AutoIt3.exe") $exe = "AutoIt3.exe" EndIf ; Assign a PID for current script. $script = @AutoItPID ; $ans = MsgBox(262177, "Close Running Instance Query", _ "'Update Mp3 Artwork' program is already running." & @LF & @LF & _ "Do you want to close it for another instance?" & @LF & @LF & _ "NOTE - If all work has been saved, and you are" & @LF & _ "trying to work on another album, then a click on" & @LF & _ "OK is recommended, else just click CANCEL, to" & @LF & _ "attempt a restore or re-activate of original." & @LF & @LF & _ $pid & " (" & $exe & ") " & $script & @LF & @LF & _ "(will default to CANCEL in 30 seconds)", 30) If $ans = 1 Then ; Attempt to close original instance, and continue with new. If $pid <> $script Then ProcessClose($pid) Else MsgBox(262192, "Close Error", "OK process failed!", 0) Exit EndIf ElseIf $ans = 2 Or $ans = -1 Then ; Attempt to retore and activate a non-active or minimized window. ; Get a list of all running programs with the same name. $wins = WinList($Scriptname, "") ; Loop through found instances and compare PID's, restoring or re-activating any match. For $w = 1 to $wins[0][0] $handle = $wins[$w][1] If WinGetProcess($handle, "") = $pid Then WinSetState($handle, "", @SW_RESTORE) WinActivate($handle, "") ExitLoop EndIf Next Exit EndIf EndIf Enjoy!
      P.S. I have a couple of programs that I regularly forget are minimized while working with another related one, so this saves me some mucking around to close and restart or restore etc. Pretty basic, but does the job well so far.
    • algiuxas
      By algiuxas
      Hello, I have a problem, I downloaded example of TCP Server and Client, but client doesn't work, It shows TCPConnect 10060 error (timeout), I tried to turn on two servers, I think server work, because one server show 10048 error(Address already in use) I don't know why it doesn't work, I edited that script, but it doesn't work still. I tried TCPConnect and TCPAccept from AutoIt3\Examples\Helpfile, but TCPConnect shows error 10060(timeout)... Anybody knows how to fix it? Thanks
      ; SERVER #include <Array.au3> TCPStartup() Dim $Socket_Data[1] $Socket_Data[0] = 0 $Listen = TCPListen(@IPAddress1, 1018, 500) If @error Then ConsoleWrite('!-->['&@Hour&":"&@MIN&":"&@SEC&'] TCPListen error. ( ' & @error & ' )' & @CRLF) Exit EndIf While 1 For $x = $Socket_Data[0] To 1 Step -1 $Recv = TCPRecv($Socket_Data[$x], 1000000) If $Recv Then MsgBox(0, 'Client Number ' & $x & ' with connected socket identifier ' & $Socket_Data[$x], "["&@Hour&":"&@MIN&":"&@SEC&"]"&' Recived msg from Client: ' & @CRLF & $Recv, 5) TCPSend($Socket_Data[$x], 'bye') TCPCloseSocket($Socket_Data[$x]) _ArrayDelete($Socket_Data, $x) $Socket_Data[0] -= 1 EndIf Next _Accept() WEnd Func _Accept() Local $Accept = TCPAccept($Listen) If $Accept <> -1 Then _ArrayAdd($Socket_Data, $Accept) $Socket_Data[0] += 1 EndIf EndFunc ;==>_Accept exit ; CLIENT $Connected = False TCPStartup() ; Start TCP. $timespentconnecting = TimerInit( ) Do $Socket = TCPConnect(@IPAddress1, 1018) ; Connect to server. $nERROR = @error ; TCPConnect @error. If not $nERROR Then ; If client connected to server. $Connected = True Else ; If TCPConnect didn't connected to server. ConsoleWrite( "["&@Hour&":"&@MIN&":"&@SEC&"] TCPConnect error. {CODE:" & $nERROR & "}"&@CRLF ) ; Show error. EndIf sleep(100) ; Sleep 0.1 secounds. Until $Connected = True or TimerDiff( $timespentconnecting ) > 10000 ; If client connected or timer > 10 secounds, stop trying connect to server. If $Connected = False then exit ; If client didn't connected to server, exit. TCPSend($Socket, 'Hi there. My computer name is' & ", " & @ComputerName & ", and its drive serial is " & DriveGetSerial(@HomeDrive)); Send to server data. Do ; Loop until client recives data from server. $Recv = TCPRecv($Socket, 1000000) ; Recive data from server. Until $Recv ; Stop looping when data recived from server. MsgBox(0, "["&@Hour&":"&@MIN&":"&@SEC&"] Recived from server:", $Recv); Show recived data from server. Exit(0) ; Exit.