delme Posted July 16, 2009 Share Posted July 16, 2009 (edited) Hey, this is just a little (but useful) script that I had posted here awhile ago, I recently updated it as it had a few major issues, but now it should be working correctly. All the info on how to use this is in the function headers below and in the headers in the file, hope you guys find this useful. If you find any bugs please let me know. Please feel free to post your questions and opinions bellow . To start an interrupted transfer from where it encountered an error you would do this: $i = _TCPFileRecv($sock, "Randomfile.exe") ;*Gets interupted* $newoffset = @extended ;@extended would be used to get the number of bytes successfully written to the file if an error had occured ;You need to communicate the number of bytes that were successfully recorded to the sending script somehow to make sure they send the file from the right offset, else the file will get corrupted. Just use a simple tcp message for this $i = _TCPFileRecv($sock, "Randomfile.exe", $newoffset) ;start writing the file from where you left off Here is the folder with the script examples: _TCPFileTransfer.zip and here is the _TCPFileTransfer.au3 file alone: _TCPFileTransfer.au3 #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.6.0 Author: DELmE Function: _TCPFileRecv Description: Receives a file being sent over a TCP connection Parameters: sock The TCP socket to be used rFile The name of the file to save to offset = 0 The offset to start writing data to the file at (to be used if the transfer is somehow interrupted) default value is 0 (no offset) $DataSize = 1024 The number of bytes of data to be received per packet, default value is 1024 Return value: Success _TCPFileRecv returns the number of bytes written to the file Failure _TCPFileRecv returns 0 if the function failed and sets @error to the following: 1 = Error opening the file 2 = Failed to set offset 3 = Failed to receive data on socket (invalid socket) 4 = Unable to write data to the file Also sets @extended to the number of bytes of data that was successfully written to the file #ce ---------------------------------------------------------------------------- #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.6.0 Author: DELmE Function: _TCPFileSend Description: Sends a file over a TCP connection Parameters: sock The tcp socket to be used sFile The file to be sent offset = 0 The offset to start reading data from the file at (to be used if the transfer is somehow interrupted) default value is 0 (no offset) $DataSize = 1024 The number of bytes of data to be sent per packet, default value is 1024 Return value: Success _TCPFileSend returns the number of bytes sent Failure _TCPFileSend returns 0 if an error occurred and sets @error to the following: 1 = The file does not exist 2 = Failed to set offset 3 = Failed to read data from file 4 = Failed to send data through socket Also sets @extended to the number of bytes of data that was successfully sent #ce ---------------------------------------------------------------------------- Updates: [5/16/2010] Changed the code completely, can now handle files of all sizes and supports offsets. Edit: Thanks to Manadar and FireFox for their help Edited May 16, 2010 by DELmE Link to comment Share on other sites More sharing options...
delme Posted July 17, 2009 Author Share Posted July 17, 2009 Nearly 40 downloads and no comments? Anyone? Link to comment Share on other sites More sharing options...
jvanegmond Posted July 17, 2009 Share Posted July 17, 2009 Ok, I had a look at the library after your desperate plee. : )But be warned, the code definitely needs some attention if you want other programmers to be able to use the library without modifying it.$TCPSend = TCPSend($TCPConn, $oFileRead) If $TCPSend = 0 Then $error = True Else $buff = BinaryMid ($oFileOpen, $TCPSend + 1, BinaryLen ($oFileOpen) - $TCPSend) Do $TCPSend = TCPSend($TCPConn, $buff) $buff = BinaryMid ($buff, $TCPSend + 1, BinaryLen ($buff) - $TCPSend) Until $buff = "" EndIfI'm not sure if I fully understand how this works, but it seems to me that you're trying to send the entire file in one piece ( regardless of size ) first and if that fails you are sending it in chunks; Why not send it in chunks immediately? The benefit of chunks is that the application will not hang and you can check for errors during the transfer. If an error occurs you should be able to reconnect and continue the file transfer on a new socket.$TCPRecv = TCPRecv($TCPAcc, 9999999) ;------------------------------^Why 9999999? Numbers like this that make no sense and should be avoided always. As a last resolution you can always ( this is bad too ): Dim Const $Infinite = 999999;TCPStartup() TCPShutdown()These two, I understand they are necessary; but give the programmer who is using the library the choice when to start up or when to shut down. Maybe he is using other TCP connections in his application and suddenly his socket is closed for no reason.Proposed solution: Remove the startup and shutdown, and tell the programmer to do it him self! : )AutoItSetOption("TCPTimeout", 2000)Again this might conflict with what the rest of the script is doing. You can reset the original option when your transfer is finished. Look this up in help file.Do $TCPAcc = TCPAccept($TCPListen) $TCPRecv = TCPRecv($TCPAcc, 9999999) $TCPDiff = TimerDiff($TCPTimerInt) If $TCPDiff >= $sTimeout Then $error = True ExitLoop EndIf Until $TCPRecv <> ""This time out is unnecesary. If the connection stays open then the receiver should just be patient until the TCP connection closes by itself or the transfer is finished.And last one:If X Then Y If Not X Then ZYou do this a lot, but it causes the expression to be evaluated twice! One time is enough, so do this instead:If X Then Y Else Z EndIfYou are definitely on your way to writing a good and simple to use library! For a beginner user of AutoIt I am already impressed. github.com/jvanegmond Link to comment Share on other sites More sharing options...
delme Posted July 17, 2009 Author Share Posted July 17, 2009 (edited) Ok, I had a look at the library after your desperate plee. : ) But be warned, the code definitely needs some attention if you want other programmers to be able to use the library without modifying it. $TCPSend = TCPSend($TCPConn, $oFileRead) If $TCPSend = 0 Then $error = True Else $buff = BinaryMid ($oFileOpen, $TCPSend + 1, BinaryLen ($oFileOpen) - $TCPSend) Do $TCPSend = TCPSend($TCPConn, $buff) $buff = BinaryMid ($buff, $TCPSend + 1, BinaryLen ($buff) - $TCPSend) Until $buff = "" EndIf I'm not sure if I fully understand how this works, but it seems to me that you're trying to send the entire file in one piece ( regardless of size ) first and if that fails you are sending it in chunks; Why not send it in chunks immediately? The benefit of chunks is that the application will not hang and you can check for errors during the transfer. If an error occurs you should be able to reconnect and continue the file transfer on a new socket. $TCPRecv = TCPRecv($TCPAcc, 9999999) ;------------------------------^ Why 9999999? Numbers like this that make no sense and should be avoided always. As a last resolution you can always ( this is bad too ): Dim Const $Infinite = 999999; TCPStartup() TCPShutdown() These two, I understand they are necessary; but give the programmer who is using the library the choice when to start up or when to shut down. Maybe he is using other TCP connections in his application and suddenly his socket is closed for no reason. Proposed solution: Remove the startup and shutdown, and tell the programmer to do it him self! : ) AutoItSetOption("TCPTimeout", 2000) Again this might conflict with what the rest of the script is doing. You can reset the original option when your transfer is finished. Look this up in help file. Do $TCPAcc = TCPAccept($TCPListen) $TCPRecv = TCPRecv($TCPAcc, 9999999) $TCPDiff = TimerDiff($TCPTimerInt) If $TCPDiff >= $sTimeout Then $error = True ExitLoop EndIf Until $TCPRecv <> "" This time out is unnecesary. If the connection stays open then the receiver should just be patient until the TCP connection closes by itself or the transfer is finished. And last one: If X Then Y If Not X Then Z You do this a lot, but it causes the expression to be evaluated twice! One time is enough, so do this instead: If X Then Y Else Z EndIf You are definitely on your way to writing a good and simple to use library! For a beginner user of AutoIt I am already impressed. Thanks for the indepth help! I will definatly take another look at the script and fix it up using all the suggestions you just gave me Edited July 17, 2009 by DELmE Link to comment Share on other sites More sharing options...
Cyber Posted July 17, 2009 Share Posted July 17, 2009 Very useful! thanks" Console Browse: Navigate on the WEB in a textual consoleMultiPing!: Show computer on the lan and/or show the local/remote task, ALL animated!KillaWin: Event executingCryptPage: Crypt your webpage and show only with key Link to comment Share on other sites More sharing options...
delme Posted July 17, 2009 Author Share Posted July 17, 2009 Very useful! thanks"Thanks Im fixing it up with Manadar's suggestions at the moment to make it more user friendly Link to comment Share on other sites More sharing options...
delme Posted July 17, 2009 Author Share Posted July 17, 2009 Manadar: I've just finished fixing up the areas that you pointed out to me but now when I transfer exe's they, for some reason, increase in size during transfer and no-longer work. I checked with my old version and found that the same thing happened when transfering larger files. This leads me to think that it has something with the way I am using the BinaryMid() function. Heres what I have: expandcollapse popup#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.0.0 Author: DELmE Script Function: _TCPFileRecv Description: Receives a file being sent over a TCP connection Parameters: rFile The name of the file to save to Ip The Ip to listen on for the file (default = @IPAddress1) Port The port to listen on for incoming file data (default = 7894) Return value: Success _TCPFileRecv returns 1 if the file was successfully received and written Failure _TCPFileRecv returns 0 if the function failed #ce ---------------------------------------------------------------------------- Func _TCPFileRecv($rFile, $Ip = @IpAddress1, $Port = 7895) If $Ip = "" Then $Ip = @IpAddress1 If $Ip = -1 Then $Ip = @IpAddress1 If $Port = "" Then $Port = 7894 If $Port = -1 Then $Port = 7894 $opt = AutoItSetOption("TCPTimeout", 2000) Local $error = False Local $buff $TCPListen = TCPListen($Ip, $Port) $no_recv_count = 0 $TCPAcc = TCPAccept($TCPListen) Do $TCPRecv = TCPRecv($TCPAcc, 100000) If $TCPRecv = "" Then $no_recv_count += 1 Else $buff &= $TCPRecv $no_recv_count = 0 EndIf Until $no_recv_count >= 15 If $buff = "" Then $error = True Else $rFileOpen = FileOpen($rFile, 16 + 2) If $rFileOpen = -1 Then $error = True Else $rFileWrite = FileWrite($rFileOpen, $buff) If $rFileWrite = 0 Then $error = True EndIf FileClose($rFileOpen) EndIf EndIf TCPCloseSocket($TCPListen) AutoItSetOption("TCPTimeout", $opt) If $error = True Then Return 0 Else Return 1 EndIf EndFunc ;==> _TCPFileRecv #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.0.0 Author: DELmE Script Function: _TCPFileSend Description: Sends a file over a TCP connection Parameters: sFile The file to be sent Ip The Ip to send on (default = @IPAddress1) Port The port to send the file data on (default = 7894) Return value: Success _TCPFileSend returns 1 if the file was successfully sent out Failure _TCPFileSend returns 0 if an error occurred #ce ---------------------------------------------------------------------------- Func _TCPFileSend($sFile, $Ip = @IPAddress1, $Port = 7895) If $Ip = -1 Then $Ip = @IPAddress1 If $Ip = "" Then $Ip = @IPAddress1 If $Port = -1 Then $Port = 7894 If $Port = "" Then $Port = 7894 $opt = AutoItSetOption("TCPTimeout", 2000) Local $error = False $sFileOpen = FileOpen($sFile, 16 + 0) $sFileRead = FileRead($sFileOpen) FileClose($sFileOpen) $sFileSize = BinaryLen($sFileRead) $TCPConn = TCPConnect($Ip, $Port) If $TCPConn = -1 Then $error = True Else If $sFileSize < 100000 Then $TCPSend = TCPSend($TCPConn, $sFileRead) If $TCPSend = 0 Then $TCPConn = TCPConnect($Ip, $Port) $TCPSend = TCPSend($TCPConn, $sFileRead) EndIf Else $buff = $sFileRead Do $TCPSend = TCPSend($TCPConn, BinaryMid($buff, 1, 100000)) If $TCPSend = 0 Then $TCPConn = TCPConnect($Ip, $Port) $TCPSend = TCPSend($TCPConn, BinaryMid($buff, 1, 100000)) EndIf $buff = BinaryMid($buff, $TCPSend + 1) Until BinaryLen($buff) = 0 EndIf EndIf TCPCloseSocket($TCPConn) AutoItSetOption("TCPTimeout", $opt) If $error = True Then Return 0 Else Return 1 EndIf EndFunc ;==> _TCPFileSend Any chance you (or anyone else who may be reading this) can point me in the right direction? Thanks Link to comment Share on other sites More sharing options...
FireFox Posted July 17, 2009 Share Posted July 17, 2009 @DELmE Take a look here : http://www.autoitscript.com/forum/index.php?showtopic=89679 Cheers, FireFox. Link to comment Share on other sites More sharing options...
delme Posted July 18, 2009 Author Share Posted July 18, 2009 @DELmETake a look here : http://www.autoitscript.com/forum/index.php?showtopic=89679Cheers, FireFox.Cool, thanks Link to comment Share on other sites More sharing options...
delme Posted July 18, 2009 Author Share Posted July 18, 2009 Hey, I'm going to be away for about 4 or 5 days so if you have any questions or comments I'll reply to them when I can DELmE Link to comment Share on other sites More sharing options...
delme Posted July 22, 2009 Author Share Posted July 22, 2009 Just got back . What did you guys think? (the people who saw the thread before it went to page 2 ) Link to comment Share on other sites More sharing options...
Cyber Posted July 27, 2009 Share Posted July 27, 2009 Hi! I have a problem >_< With big file (more than 19 mega) the script goes in "memory error" Is there a solution? thanks! Console Browse: Navigate on the WEB in a textual consoleMultiPing!: Show computer on the lan and/or show the local/remote task, ALL animated!KillaWin: Event executingCryptPage: Crypt your webpage and show only with key Link to comment Share on other sites More sharing options...
delme Posted July 29, 2009 Author Share Posted July 29, 2009 (edited) Hi!I have a problem >_< With big file (more than 19 mega) the script goes in "memory error" Is there a solution?thanks!Hmm. I dunno what that is. Never happened to me. Do you have any other programs open that are using TCP or UDP?Edit: I'm thinking that it may be because while the file is being sent the data is stored in a variable and maybe 19MB of data passes the length that AutoIt can carry in a variable, just taking a stab though as I don't really know.. Edited July 29, 2009 by DELmE Link to comment Share on other sites More sharing options...
Xwolf Posted October 13, 2009 Share Posted October 13, 2009 (edited) Gob jobS. Thanks. But i encounter some problems. Success when i used it to transfer .txt files. Fail when i used it to transfer .rar or .exe files. Edited October 13, 2009 by Xwolf Link to comment Share on other sites More sharing options...
delme Posted May 16, 2010 Author Share Posted May 16, 2010 Currently updating this code so that it will be able to handle files of any size, and will be able to re-start an interrupted transfer from where it was left off. Link to comment Share on other sites More sharing options...
delme Posted May 16, 2010 Author Share Posted May 16, 2010 (edited) Finished the update, just scrapped the old version and wrote a new one . The code is now 100 times better Edited May 16, 2010 by DELmE Link to comment Share on other sites More sharing options...
lsakizada Posted May 16, 2010 Share Posted May 16, 2010 I have done basic test. A file (*.tar.gz) with 86MB pass successfully via my company network. Be Green Now or Never (BGNN)! Link to comment Share on other sites More sharing options...
delme Posted May 16, 2010 Author Share Posted May 16, 2010 I have done basic test. A file (*.tar.gz) with 86MB pass successfully via my company network.Cool, good to hear Link to comment Share on other sites More sharing options...
TheBrainiac Posted April 30, 2011 Share Posted April 30, 2011 (edited) Hey guys, I'm having some problems with the server: I tried to transfer a file over the internet using my external IP and an open port. What happens is that sometimes, everything works just perfectly, but often the server does not close the file handle after the transfer has finished. You send a "close handle" request to the server with those two line breaks (line 147 I think). I tried using a different string for the request and replaced If $rBuff = "WMpHUWr0FEZg" Then with If stringright($rBuff,12) = "WMpHUWr0FEZg" Then which made it a little more reliable, but it still doesn't work every time. Any ideas? Edited April 30, 2011 by TheBrainiac Link to comment Share on other sites More sharing options...
incepator Posted April 22, 2013 Share Posted April 22, 2013 (edited) very very useful this UDF, but you can implement a function of ProgressOn? It would be nice to be able to see how to get the bits in a progressbar. thanks ! Edited April 23, 2013 by incepator Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now