Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: sSendBinary sRecvLine sRecvBinary sSendLine Client Server Socket Listen Listener Remote Port Chunks Connect Connector File Transfer
;-------------------------------------------------------------------------------------- ; FILE TRANSER - The SERVER LISTENER script ; ; Sets up a socket to listen for remote connects for multiple ports ; Prompts user for the Directory they want to transfer then sends all the ; Directories and Files in chunks to Client. ;-------------------------------------------------------------------------------------- ; ; Keywords: sSendBinary sRecvLine Server Socket Listen Listener Remote Port Chunks File Transfer ; ; Issues Fixed: ; 2013.01.18 ; * Added Code Comments ; * Freed the binary buffers created with BinaryAlloc uisng BinaryFree. ; * Closed the open log file handle using FileClose. ; ; NOTES: ; Binary Buffer format ; OLD {Buffer handle} ; NEW {Buffer handle} ; ; This code uses an array to globally point to two file buffers. It interchangeably uses the ; two to store data or send data. It stores data in one buffer ("old") until it is "filled", ; then fill the other ("new"). Once the "new" is filled, it pust the EOD of the "new" into ; the "old" so that the client computer is aware of the server's next buffer size approaching ; (this is INTEGRAL to using sRecvBinary, otherwise it hangs). After sending the "old", it then ; swaps the two using the labels (old and new) so that they can be reused. This is a bit of an ; advanced approach when it comes to educating programmers and a better example may be developed ; for that purpose using what I've made. ; ; Developed by Trent Torkelson ; Modified by Deana Falk 2013.01.18 ;-------------------------------------------------------------------------------------- AddExtender("WWHUG34I.DLL") ; HugeMath Extender AddExtender("WWWSK44I.DLL") ; Winsock Extender IntControl(5,1,0,0,0) ; Controls whether system & hidden files or directories are seen and processed. IntControl(39,0,0,0,0) ; Sets the file sharing mode for file reads. (prevent the file from being shared ) GoSub UDFs BoxTitle("Total Sent: 0 Bytes To: No Client (Ctrl+Break to Quit)") ;-------------------------------------------------------------------------------------- ; Allocate Two Large Binary Buffers and Store the Handles in an Array called bufarr_ptr ;-------------------------------------------------------------------------------------- PtrGlobalDefine(bufarr_ptr) bufarr_ptr = ArrDimension(2,2) bufarr_ptr[0,0] = "old" bufarr_ptr[1,0] = "new" bufarr_ptr[0,1] = BinaryAlloc(1000000) bufarr_ptr[1,1] = BinaryAlloc(1000000) BinaryEodSet(bufarr_ptr[0,1],0) BinaryEodSet(bufarr_ptr[1,1],0) ;-------------------------------------------------------------------------------------- ; Define an Error Log to Store Error Info ;-------------------------------------------------------------------------------------- PtrGlobalDefine(errorlogh_ptr) errorlogh_ptr = FileOpen( DirScript():"\s_errorlog.txt","WRITE") ;-------------------------------------------------------------------------------------- ; Define Port Numbers ;-------------------------------------------------------------------------------------- portlist = "20000":@TAB:"30000":@TAB:"40000":@TAB:"50000":@TAB:"60000" portnum = AskItemlist("Choose Server/Listener Port",portlist, @TAB, @UNSORTED, @SINGLE, @TRUE ) ;-------------------------------------------------------------------------------------- ; Define Folder you would like to Transer to the Client ;-------------------------------------------------------------------------------------- thissourceroot = 'C:\TEMP\DATA\Access';AskDirectory("Select a folder to transfer: ","",Environment("SYSTEMDRIVE"),"",0) If StrSub(thissourceroot,StrLen(thissourceroot),1)=="\" Then thissourceroot=StrSub(thissourceroot,1,StrLen(thissourceroot)-1) ; Remove Trailing backslash ;-------------------------------------------------------------------------------------- ; Define chunksize of the file to send ; Don't change unless you also modify the udfGetMaxBuffer() function chunksize to match ;-------------------------------------------------------------------------------------- chunksize = 250000 ;-------------------------------------------------------------------------------------- ; sOpen - Open a Listing Socket ;-------------------------------------------------------------------------------------- listensocket = sOpen() ;-------------------------------------------------------------------------------------- ; Sets Up a Socket to Listen for Remote Connects on Multiple Ports ;-------------------------------------------------------------------------------------- listensocket = udfGetCon(listensocket,portnum) If !IsNumber(listensocket) Message('Error','No Connection could be established: "':listensocket:'"') sClose(listensocket) Goto CleanUp Exit EndIf ;-------------------------------------------------------------------------------------- ; Define How Long to Wait for a Connection from a Client ( -1 Wait Forever) ;-------------------------------------------------------------------------------------- datasocket = udfWaitForCon(listensocket,-1) If datasocket==0 Message("Error",'No Connection could be established: "Destination connection timed out or local socket connection was terminated"') sClose(listensocket) Goto CleanUp Exit EndIf ;-------------------------------------------------------------------------------------- ; Initialize the Buffer Size in the Array as Zero ;-------------------------------------------------------------------------------------- udfSetBufferInfoSize(bufarr_ptr[udfGetBufferByType(bufarr_ptr,"old"),1],0) udfSetBufferInfoSize(bufarr_ptr[udfGetBufferByType(bufarr_ptr,"new"),1],0) ; Start by recreating the . Checks if there is enough room in buffer for the Root directory udfDirCreate(thissourceroot,bufarr_ptr[udfGetBufferByType(bufarr_ptr,"old"),1],chunksize,"r") ; Sets the EOD in the binary buffer udfFixBufferSize(bufarr_ptr[udfGetBufferByType(bufarr_ptr,"old"),1],chunksize) ;Pass short name of the root directory to start cloning the Directory Tree rslt = udfSrvCloneDirTree (thissourceroot,udfGet83Path(thissourceroot,"dir"),chunksize,@TRUE,0,datasocket,-1) ;-------------------------------------------------------------------------------------- ; Clean up any Open Handles before exiting ;-------------------------------------------------------------------------------------- :CleanUp sClose( listensocket ) BinaryFree( bufarr_ptr[0,1] ) BinaryFree( bufarr_ptr[1,1] ) FileClose( errorlogh_ptr ) Exit ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ; UDFs ;-------------------------------------------------------------------------------------- :UDFs #DefineFunction udfErrorHandler(errors) ;Error Handler - Currently does nothing. Return(1) #EndFunction #DefineFunction udfHuge_Compare(a,b) ; Compares two huge numbers and Return a value. ; 1 first parameter bigger than second parameter ; 0 parameters are the same ; -1 first parameter is smaller than the second parameter. c=huge_Subtract(a,b) If StrSub(c,1,1)=="-" Then x=-1 If StrSub(c,1,1)!="-" && c=="0" Then x=0 If StrSub(c,1,1)!="-" && c!="0" Then x=1 Return x #EndFunction #DefineFunction udfHex2Uni(value) ; Converts a hex string to a Unicode string. IntControl(73,3,0,"udfErrorHandler",0) Return ChrHexToUnicode(value) #EndFunction #DefineFunction udfBinaryReadEx(filebuf,binoffset,fn,curoffset,chunksize) ; Reads a portion of a file into a binary buffer. IntControl(73,3,0,"udfErrorHandler",0) bytesread=BinaryReadEx(filebuf,binoffset,fn,curoffset,chunksize) If bytesread==0 Then bytesread="zerolength" Return bytesread #EndFunction ;#DefineFunction udfBinaryWriteEx(filebuf,binoffset,nfn2,curoffset,chunksize) ; Writes a portion of a binary buffer to a file. ; IntControl(73,3,0,"udfErrorHandler",0) ; byteswritten=BinaryWriteEx(filebuf,binoffset,nfn2,curoffset,chunksize) ; If byteswritten==0 then byteswritten="zerolength" ; Return byteswritten ;#EndFunction #DefineFunction udfGetText(str) If ChrUnicodeToString(str)!=str Then str=ChrUnicodeToHex(str) Return str #EndFunction ;#DefineFunction udfGetText2(str) ; If StrTypeInfo(StrTypeInfo(str,0),-1)=="HexDg" && StrCmp(str,strupper(str))==0 && strlen(str)>3 then str=udfhex2Uni(str) ; Return str ;#EndFunction #DefineFunction udfGetMaxBuffer(filebuf,fsize,fileoffset,binoffset) ; Determine If user specified too Large of a chunkssize chunksize=250000 midspaceleft=huge_Subtract(600000,binoffset) maxspaceleft=huge_Subtract(1000000,binoffset) ;Determine how much of the File is Left to Read fileleft=huge_Subtract(fsize,fileoffset) ;If the Remaining File is Greater than the Chunksize If udfHuge_Compare(fileleft,chunksize)==1 ;If the Remaining File is Greater than the Maxspaceleft If udfHuge_Compare(fileleft,maxspaceleft)==1 Then chunksize=maxspaceleft Else chunksize=midspaceleft EndIf ;Returns updated Chunksize Return chunksize #EndFunction #DefineFunction udfGetCon(listensocket,portnum) ;Sets up a socket to listen for remote connects for multiple ports ctr=0 gotcon=@FALSE errstr="Unknown Error" For i=1 To ItemCount(portnum,@TAB) sListen(listensocket,ItemExtract(i,portnum,@TAB)) ;Pause( "PortNum",ItemExtract(i,portnum,@TAB));DEBUG datasocket=sAccept(listensocket,@FALSE) If datasocket == 0 err=wxGetLastErr() If err!="12" errstr=wxGetErrDesc(err) ctr=ctr+1 Else gotcon=@TRUE EndIf Else gotcon=@TRUE EndIf If gotcon==@TRUE Then Break Next If gotcon==@FALSE Then Return errstr Return listensocket #EndFunction #DefineFunction udfWaitForCon(listensocket,maxwait) ;Waits for a Client/Connecter to Connect curwait=-1 nocon=@FALSE newcon=@FALSE datasocket=0 While curwait<=maxwait && newcon==@FALSE datasocket=sAccept(listensocket,@FALSE) If datasocket == 0 err=wxGetLastErr() If err=="12" If maxwait>-1 Then curwait=curwait+0.5 TimeDelay(.5) Else nocon=@TRUE EndIf Else newcon=@TRUE EndIf If nocon==@TRUE Then Break EndWhile Return datasocket #EndFunction #DefineFunction udfGet83Path(path,type) ; Used to deal with Long file/directory names and 20+ length folder structures might exist. ; Compensates with checks on recursive functions to prevent nesting errors, as well as shorten ; path names to prevent fileopen and filecopy errors. IntControl(73,3,0,"udfErrorHandler",0) If StrSub(path,1,2)=="\\" Then mode="share" Else mode="local" file=ItemExtract(-1,path,"\") If type=="file" Then path=ItemRemove(-1,path,"\") If mode=="local" newpath=ItemExtract(1,path,"\") For i=2 To ItemCount(path,"\")-1 newpath=FileNameShort(ItemInsert(ItemExtract(i,path,"\"),-1,newpath,"\")) Next If ItemCount(path,"\")>1 Then newpath=ItemInsert(ItemExtract(-1,path,"\"),-1,newpath,"\") Else newpath="\\":ItemExtract(3,path,"\"):"\":ItemExtract(4,path,"\") For i=5 To ItemCount(path,"\")-1 newpath=FileNameShort(ItemInsert(ItemExtract(i,path,"\"),-1,newpath,"\")) Next If ItemCount(path,"\")>4 Then newpath=ItemInsert(ItemExtract(-1,path,"\"),-1,newpath,"\") EndIf If newpath==0 || newpath=="" Then Return path If type=="file" Then newpath=ItemInsert(file,-1,newpath,"\") Return newpath #EndFunction ;#DefineFunction udfGetLongPath(path) ; IntControl(73,3,0,"udfErrorHandler",0) ; newpath=path ; newpath=filenamelong(path) ; If itemcount(newpath,"\")==itemcount(path,"\") && strlen(newpath)<250 then Return newpath ; Else Return path ;#EndFunction #DefineFunction udfAppendStr2List(str,arr) ;Accepts Directory Path and an Array ;Fills Array with Full Filepaths of All the Files Found If arr[0,0]==0 Then Return arr For i=1 To arr[0,0] arr[i,0]=str:arr[i,0] Next Return arr #EndFunction #DefineFunction udfSrvCloneDirTree (srcroot,srcroot83,chunksize,firstrun,cntr,datasocket,maxwait) ;Debug(1) cntr = cntr+1 ; Keep track of recurive calls If cntr>21 Then Return ; Avoid drilling to deep bufarr = PtrGlobal(bufarr_ptr) ; Get Access to Global Array Variable that Contains the Buffers topdirarr = DirInfoToArray(srcroot83:"\*.*",1) ; Return Directory Information, as an array. tempfilesarr = FileInfoToArray(srcroot83:"\*.*",1) ; Return File Information, as an array. ; Add the Directory to the Directory Array topdirarr = udfAppendStr2List(srcroot:"\",topdirarr) ; Add the Files to the File Array tempfilesarr = udfAppendStr2List(srcroot:"\",tempfilesarr) ; If No Directories and Files Found then Return False If topdirarr[0,0] == 0 && tempfilesarr[0,0] == 0 Then Return @FALSE ; Loop Thru all of the Directories For j=1 To topdirarr[0,0] dir=topdirarr[j,0] ;Get Directory ; Send CMD to Client to Create a Directory dircomplete=udfDirCreate(dir,*bufarr[udfGetBufferByType(*bufarr,"new"),1],chunksize,"s") While dircomplete==@FALSE udfSendBuffer(chunksize,0,datasocket,maxwait) ;test setup, to test valid structure of buffer chunk. dircomplete=udfDirCreate(dir,*bufarr[udfGetBufferByType(*bufarr,"new"),1],chunksize,"s") EndWhile ; Recurse udfSrvCloneDirTree (dir,udfGet83Path(dir,"dir"),chunksize,@FALSE,cntr,datasocket,maxwait) Next ;If There are Files to be Copied If tempfilesarr[0,0] != 0 ; Loop Thru all of the Files For k=1 To tempfilesarr[0,0] curfile=tempfilesarr[k,0] ;Get File ; Send CMD to Client to Get a File filecomplete=udfCopyFile(curfile,udfGet83Path(curfile,"file"),*bufarr[udfGetBufferByType(*bufarr,"new"),1],chunksize,0) While filecomplete>-1 udfSendBuffer(chunksize,0,datasocket,maxwait) ;test setup, to test valid structure of buffer chunk. filecomplete=udfCopyFile(curfile,udfGet83Path(curfile,"file"),*bufarr[udfGetBufferByType(*bufarr,"new"),1],chunksize,filecomplete) EndWhile Next EndIf ; Checks if functions first run, and if so cleaning out the buffers since the call is coming to an end, and no more objects are left to collect. ; EOD check on "new" buffer is to See if its clear and if so, make one call. The last sendbuffer call sends whats left of the "old" buffer" If firstrun==@TRUE If BinaryEodGet(*bufarr[udfGetBufferByType(*bufarr,"new"),1])>0 Then udfSendBuffer(chunksize,0,datasocket,maxwait) udfSendBuffer(chunksize,0,datasocket,maxwait) EndIf Return @TRUE #EndFunction #DefineFunction udfCopyFile(curfile,curfile83,filebuf,chunksize,fileoffset) errorlogh=PtrGlobal(errorlogh_ptr) newfileoffset=fileoffset openfile=@FALSE ;Check If the File Exists and is Not Read Deny If FileExist(curfile83)==2 openfile=@TRUE FileWrite(*errorlogh,curfile:" - file is in read-deny mode.") EndIf ;If there was a problem Return -1 If openfile==@TRUE Then Return -1 ;Get the File Size of the File fsize=FileSize(curfile83,1) noroom=@FALSE ; Tell the Client Your Sending a File be sure to Include the FileSize ; so the Client Knows How Many Bytes to Read If fileoffset==0 ; CMD Marker that includes Filename, FileSize and File Type to the End of the File finfo="CMD_!@{{":udfGetText(curfile):"|":fsize:"|":"f}}@!_CMD" infolen=StrByteCount(finfo,0) ; If Data is Less than the Chunksize Put in buffer If udfHuge_Compare(huge_Add(BinaryEodGet(filebuf),infolen),chunksize)==-1 BinaryPokeStr(filebuf,BinaryEodGet(filebuf),finfo) Else noroom=@TRUE EndIf Else ; Only called If user specified too Large of a chunkssize chunksize=udfGetMaxBuffer(filebuf,fsize,fileoffset,BinaryEodGet(filebuf)) EndIf If noroom==@TRUE Then Return newfileoffset filechunk=0 ; Determine How Much Room there is in the Buffer spaceleft=huge_Subtract(chunksize,BinaryEodGet(filebuf)) ; Determine How Much of the File is Left to Send fileleft=huge_Subtract(fsize,fileoffset) ; Determine New File Offset If udfHuge_Compare(fileleft,spaceleft)==1 filechunk=spaceleft newfileoffset=huge_Add(newfileoffset,filechunk) Else filechunk=fileleft newfileoffset=-1 EndIf ; Reads File into a Binary Buffer in Chunks until There is None Left While udfBinaryReadEx(filebuf,BinaryEodGet(filebuf),curfile83,fileoffset,filechunk)==0 TimeDelay(.5) EndWhile ;Write to Log About Problems Rading the File If newfileoffset==-1 If fsize!=FileSize(curfile83,1) Then FileWrite(*errorlogh,curfile:" - file could not be fully read.") EndIf Return newfileoffset #EndFunction #DefineFunction udfDirCreate(dir,filebuf,chunksize,type) ; r = root directory ; s = sub directory ; f = file dinfo="CMD_!@{{":udfGetText(dir):"|":type:"}}@!_CMD" infolen=StrByteCount(dinfo,0) noroom=@FALSE ; If there is room put the marker in the file buffer If udfHuge_Compare(huge_Add(BinaryEodGet(filebuf),infolen),chunksize)==-1 BinaryPokeStr(filebuf,BinaryEodGet(filebuf),dinfo) Else noroom=@TRUE EndIf If noroom==@TRUE Then Return @FALSE Return @TRUE #EndFunction #DefineFunction udfSendBuffer(chunksize,cntr,datasocket,maxwait) ; Sends Data in the Buffer to the Client in Chunks bufarr=PtrGlobal(bufarr_ptr) rqst="" curwait=-1 ; Determine Size of New Buffer totalsize=BinaryEodGet(*bufarr[udfGetBufferByType(*bufarr,"new"),1]) If totalsize<=7 Then totalsize=0 udfSetBufferInfoSize(*bufarr[udfGetBufferByType(*bufarr,"old"),1],totalsize) sentbytes=BinaryEodGet(*bufarr[udfGetBufferByType(*bufarr,"old"),1]) ; Wait for CMD_GETDATA Request from Client rqst=sRecvLine(datasocket,100) While rqst!="!@CMD_GETDATA@!" && curwait<=maxwait TimeDelay(.5) If maxwait>-1 Then curwait=curwait+1 rqst=sRecvLine(datasocket,100) EndWhile ; Sends binary data of the OLD Buffer to the Socket sSendBinary(datasocket,IntControl(42,*bufarr[udfGetBufferByType(*bufarr,"old"),1],0,0,0),sentbytes) ; Update Box Title with teh number of wincap=WinName() ; Adds sentbytes to the existing title of the box BoxTitle("Total Sent: ":huge_Add(sentbytes,StrSub(wincap,13,(StrIndex(wincap,"B",1,@FWDSCAN)-1)-13)):" Bytes To: ":wxGetInfo(2,datasocket):" (Ctrl+Break to Quit)") ; After sending the "old" Buffer, swap the two buffers using the labels (old and new) so that they can be reused. udfSwapBufferType() ;Set the New buffers End of Data to Zero BinaryEodSet(*bufarr[udfGetBufferByType(*bufarr,"new"),1],0) udfSetBufferInfoSize(*bufarr[udfGetBufferByType(*bufarr,"new"),1],0) Return #EndFunction ;#DefineFunction udfDiskExistance(path) ; IntControl(73,3,0,"udfErrorHandler",0) ; Return DiskExist(path) ;#EndFunction ; ;#DefineFunction udfDirCreate2(path) ; Create the Directory ; IntControl(73,3,0,"udfErrorHandler",0) ; dirtest=dirmake(path) ;; IntControl(73,3,0,"generr",0) ; If dirtest==@TRUE || udfDiskExistance(path)==@TRUE then Return @TRUE ; Else Return @FALSE ;#EndFunction #DefineFunction udfSetBufferInfoSize(filebuf,bufsize) ; Insert 7 bytes Indicating the File Size bufsize=StrFixBytes(bufsize,"?",7) BinaryPokeStr(filebuf,0,bufsize) #EndFunction #DefineFunction udfFixBufferSize(filebuf,bufsize) ; Updates a Buffers end of Data BinaryEodSet(filebuf,bufsize) Return spaceleft=huge_Subtract(bufsize,BinaryEodGet(filebuf)) bufpad=StrFixBytes("","0",spaceleft) BinaryPokeStr(filebuf,BinaryEodGet(filebuf),bufpad) udfSetBufferInfoSize(filebuf,bufsize) Return #EndFunction #DefineFunction udfSwapBufferType() ;After sending the "old" Buffer, swap the two buffers using the labels (old and new) so that they can be reused. bufarr=PtrGlobal(bufarr_ptr) If *bufarr[0,0]=="new" Then *bufarr[0,0]="old" Else *bufarr[0,0]="new" If *bufarr[1,0]=="new" Then *bufarr[1,0]="old" Else *bufarr[1,0]="new" Return #EndFunction #DefineFunction udfGetBufferByType(bufarr,type) ; Determines the Buffer Type Old or New. If bufarr[0,0]==type Then Return 0 If bufarr[1,0]==type Then Return 1 Return #EndFunction Return
Client - Receive File Transer
;-------------------------------------------------------------------------------------- ; FILE TRANSER - The CLIENT CONNECTOR script ; ; Sets up a socket to connect to a remote computer. ; Prompts the user for the Directory they want store transfered files to ; then reads all the transferred Directories and Files in chunks and ; stores them in the specified directory. ;-------------------------------------------------------------------------------------- ; ; Keywords: sRecvBinary sSendLine Client Socket Connect Connector File Transfer ; ; Issues Fixed: ; 2013.01.18 ; * Added Code Comments ; * Freed the binary buffers created with BinaryAlloc uisng BinaryFree. ; * Closed the open log file handle using FileClose. ; * Closed Open Socket. ; ; NOTES: ; sRecvBinary needs to know the actual filesize. The Server script sends this information ; using the start marker CMD_!@{{ and the end marker }}@!CMD ; ; Developed by Trent Torkelson ; Modified by Deana Falk 2013.01.18 ;-------------------------------------------------------------------------------------- AddExtender("WWHUG34I.DLL") ; HugeMath Extender AddExtender("WWWSK44I.DLL") ; Winsock Extender IntControl(5,1,0,0,0) ; Controls whether system & hidden files or directories are seen and processed. IntControl(39,0,0,0,0) ; Sets the file sharing mode for file reads. (prevent the file from being shared ) GoSub UDFs BoxTitle("Total Recv: 0 Bytes From: No Server") BoxesUp("200,200,800,800",@NORMAL) ; Prompts for the Directory to Save the Files Transfered from the Server. redir = 'C:\TEMP\DATAOUT'; AskDirectory("Select a folder to place files: ","",Environment("SYSTEMDRIVE"),"",0) If StrSub(redir,StrLen(redir),1)=="\" Then redir=StrSub(redir,1,StrLen(redir)-1) ; Remove Trailing backslash ; Prompts For Host Name and Port Number to Connect to serverhost = AskLine("Source Host",'Type the server in the format "NAMEORIPADDRESS:PORTNUMBER',"Localhost:20000") ;-------------------------------------------------------------------------------------- ; sOpen - Open a Data Socket ;-------------------------------------------------------------------------------------- datasocket = sOpen() ret=@FALSE While ret!=@TRUE BoxTitle("Attempting Connection to ":ItemExtract(1,serverhost,":"):" on port ":ItemExtract(2,serverhost,":"):" (Ctrl+Break to Quit)") ; Connects to Server Socket ret=sConnect(datasocket,ItemExtract(1,serverhost,":"),ItemExtract(2,serverhost,":")) If ret==@FALSE Then TimeDelay(5) EndWhile ;-------------------------------------------------------------------------------------- ; Allocate Binary Buffer to Store the Data ;-------------------------------------------------------------------------------------- maxsize=250000 filebuf=BinaryAlloc(1000000) BinaryEodSet(filebuf,0) PtrGlobalDefine(errorlogh_ptr) ;-------------------------------------------------------------------------------------- ; Define an Error Log to Store Error Info ;-------------------------------------------------------------------------------------- errorlogh_ptr=FileOpen(DirScript():"\c_errorlog.txt","WRITE") ;-------------------------------------------------------------------------------------- ; Get Start Time ;-------------------------------------------------------------------------------------- stime = TimeYmdHms() rslt = udfCliCloneDirTree(redir,udfGet83Path(redir,"dir"),filebuf,maxsize,datasocket,-1) ;-------------------------------------------------------------------------------------- ; Get End Time ;-------------------------------------------------------------------------------------- etime = TimeYmdHms() ;-------------------------------------------------------------------------------------- ; Display Results ;-------------------------------------------------------------------------------------- If rslt==@FALSE Then Message("Error","Directory transfer incomplete.") Else Message("Success","Transfer Successful":@CRLF:"start time: ":stime:@CRLF:"end time: ":etime) ;-------------------------------------------------------------------------------------- ; Clean up any Open Handles before exiting ;-------------------------------------------------------------------------------------- :CleanUp sClose( datasocket ) BinaryFree( filebuf ) FileClose( errorlogh_ptr ) Exit ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------- ; UDFs ;-------------------------------------------------------------------------------------- :UDFs #DefineFunction udfErrorHandler(errors) ; Error Handler - Currently does nothing. Return(1) #EndFunction #DefineFunction udfHuge_Compare(a,b) ; Compares two huge numbers and Return a value. ; 1 first parameter bigger than second parameter ; 0 parameters are the same ; -1 first parameter is smaller than the second parameter. c=huge_Subtract(a,b) If StrSub(c,1,1)=="-" Then x=-1 If StrSub(c,1,1)!="-" && c=="0" Then x=0 If StrSub(c,1,1)!="-" && c!="0" Then x=1 Return x #EndFunction #DefineFunction udfHex2Uni(value) ; Converts a hex string to a Unicode string. IntControl(73,3,0,"udfErrorHandler",0) Return ChrHexToUnicode(value) #EndFunction ;#DefineFunction udfGetText(str) ; If ChrUnicodeToString(str)!=str then str=ChrUnicodeToHex(str) ; Return str ;#EndFunction #DefineFunction udfGetText2(str) If StrTypeInfo(StrTypeInfo(str,0),-1)=="HexDg" && StrCmp(str,StrUpper(str))==0 && StrLen(str)>3 Then str=udfHex2Uni(str) Return str #EndFunction #DefineFunction udfBinaryWriteEx(filebuf,binoffset,nfn2,curoffset,readsize) ; Writes a portion of a binary buffer to a file. IntControl(73,3,0,"udfErrorHandler",0) byteswritten=BinaryWriteEx(filebuf,binoffset,nfn2,curoffset,readsize) If byteswritten==0 Then byteswritten="zerolength" Return byteswritten #EndFunction ;#DefineFunction udfGetMaxBuffer(filebuf,fsize,fileoffset,binoffset) ; ; Determine If user specified too Large of a chunkssize ; chunksize=250000 ; midspaceleft=huge_subtract(600000,binoffset) ; maxspaceleft=huge_subtract(1000000,binoffset) ; ;Determine how much of the File is Left to Read ; fileleft=huge_subtract(fsize,fileoffset) ; ;If the Remaining File is Greater than the Chunksize ; If udfHuge_Compare(fileleft,chunksize)==1 ; ;If the Remaining File is Greater than the Maxspaceleft ; If udfHuge_Compare(fileleft,maxspaceleft)==1 then chunksize=maxspaceleft ; Else chunksize=midspaceleft ; EndIf ; ;Returns updated Chunksize ; Return chunksize ;#EndFunction #DefineFunction udfGet83Path(path,type) ; Used to deal with Long file/directory names and 20+ length folder structures might exist. ; Compensates with checks on recursive functions to prevent nesting errors, as well as shorten ; path names to prevent fileopen and filecopy errors. IntControl(73,3,0,"udfErrorHandler",0) If StrSub(path,1,2)=="\\" Then mode="share" Else mode="local" file=ItemExtract(-1,path,"\") If type=="file" Then path=ItemRemove(-1,path,"\") If mode=="local" newpath=ItemExtract(1,path,"\") For i=2 To ItemCount(path,"\")-1 newpath=FileNameShort(ItemInsert(ItemExtract(i,path,"\"),-1,newpath,"\")) Next If ItemCount(path,"\")>1 Then newpath=ItemInsert(ItemExtract(-1,path,"\"),-1,newpath,"\") Else newpath="\\":ItemExtract(3,path,"\"):"\":ItemExtract(4,path,"\") For i=5 To ItemCount(path,"\")-1 newpath=FileNameShort(ItemInsert(ItemExtract(i,path,"\"),-1,newpath,"\")) Next If ItemCount(path,"\")>4 Then newpath=ItemInsert(ItemExtract(-1,path,"\"),-1,newpath,"\") EndIf If newpath==0 || newpath=="" Then Return path If type=="file" Then newpath=ItemInsert(file,-1,newpath,"\") Return newpath #EndFunction ;#DefineFunction udfGetLongPath(path) ; IntControl(73,3,0,"udfErrorHandler",0) ; newpath=path ; newpath=filenamelong(path) ; If itemcount(newpath,"\")==itemcount(path,"\") && strlen(newpath)<250 then Return newpath ; Else Return path ;#EndFunction ;#DefineFunction udfAppendStr2List(str,arr) ; ;Accepts Directory Path and an Array ; ;Fills Array with Full Filepaths of All the Files Found ; If arr[0,0]==0 then Return arr ; For i=1 to arr[0,0] ; arr[i,0]=str:arr[i,0] ; Next ; Return arr ;#EndFunction #DefineFunction udfDiskExistance(path) IntControl(73,3,0,"udfErrorHandler",0) Return DiskExist(path) #EndFunction #DefineFunction udfDirCreate2(path) ; Create the Directory IntControl(73,3,0,"udfErrorHandler",0) dirtest=DirMake(path) ; IntControl(73,3,0,"generr",0) If dirtest==@TRUE || udfDiskExistance(path)==@TRUE Then Return @TRUE Else Return @FALSE #EndFunction #DefineFunction udfGetBuffer(filebuf,maxsize,redir,cntr) ;Retrieve the Contents of the Buffer cntr=cntr+1 If cntr>21 Then Return errorlogh=PtrGlobal(errorlogh_ptr) ptr_bufdata=PtrPersistent(bufdata,"") ptr_fileoffset=PtrPersistent(fileoffset,0) ptr_binoffset=PtrPersistent(binoffset,7) ptr_srcroot=PtrPersistent(srcroot,"") data=@TRUE If *ptr_bufdata=="" ; Look for CMD marker structure=BinaryTagInit(filebuf,"CMD_!@{{","}}@!_CMD") structure=BinaryTagFind(structure) If structure!="" *ptr_bufdata=BinaryTagExtr(structure,0) infolength=BinaryTagLen(structure,1) *ptr_binoffset=huge_Add(*ptr_binoffset,infolength) BinaryTagRepl(structure,StrFill("0",infolength)) Else data=@FALSE *ptr_fileoffset=0 *ptr_binoffset=7 BinaryEodSet(filebuf,0) EndIf EndIf If data==@FALSE Then Return objtype=ItemExtract(-1,*ptr_bufdata,"|") ;-------------------------------------------------------------------------------------- ; Subdirectory ;-------------------------------------------------------------------------------------- If objtype=="s" ;Subdirectory dirname=udfGetText2(ItemExtract(1,*ptr_bufdata,"|")) dirname=StrReplace(dirname,*ptr_srcroot,redir) dirname=udfGet83Path(dirname,"dir") udfDirCreate2(dirname) *ptr_bufdata="" *ptr_fileoffset=0 ;-------------------------------------------------------------------------------------- ; File ;-------------------------------------------------------------------------------------- ElseIf objtype=="f" ;File filename=udfGetText2(ItemExtract(1,*ptr_bufdata,"|")) file_size=ItemExtract(2,*ptr_bufdata,"|") If filename=="" || file_size=="" Message("Error","Invalid File Information Found.") Exit EndIf filename=StrReplace(filename,*ptr_srcroot,redir) filename=udfGet83Path(filename,"file") spaceleft=huge_Subtract(maxsize,*ptr_binoffset) fileleft=huge_Subtract(file_size,*ptr_fileoffset) If udfHuge_Compare(fileleft,spaceleft)==1 Then filechunk=spaceleft Else filechunk=fileleft While udfBinaryWriteEx(filebuf,*ptr_binoffset,filename,*ptr_fileoffset,filechunk)==0 TimeDelay(.5) EndWhile *ptr_binoffset=huge_Add(*ptr_binoffset,filechunk) *ptr_fileoffset=huge_Add(*ptr_fileoffset,filechunk) If *ptr_fileoffset==file_size If file_size!=FileSize(filename,1) Then FileWrite(*errorlogh,filename:" - file could not be fully written.") *ptr_fileoffset=0 *ptr_bufdata="" EndIf Else ;-------------------------------------------------------------------------------------- ; Directory Root ;-------------------------------------------------------------------------------------- If objtype=="r" ;Directory Root *ptr_srcroot=udfGetText2(ItemExtract(1,*ptr_bufdata,"|")) *ptr_bufdata="" *ptr_fileoffset=0 EndIf EndIf If *ptr_binoffset==maxsize BinaryEodSet(filebuf,0) *ptr_binoffset=7 data=@FALSE EndIf If data==@FALSE Then Return udfGetBuffer(filebuf,maxsize,redir,cntr) Return #EndFunction #DefineFunction udfCliCloneDirTree(redir,redir83,filebuf,maxsize,datasocket,maxwait) recvbytes=0 dataleft=@TRUE ; Loop Until All Data is Recieved While maxsize>0 ret=@FALSE curwait=-1 ; Send Request to Server to Start File Transer ret=sSendLine(datasocket,"!@CMD_GETDATA@!") While ret==@FALSE && curwait<=maxwait TimeDelay(.5) If maxwait>-1 Then curwait=curwait+1 ret=sSendLine(datasocket,"!@CMD_GETDATA@!") EndWhile If ret==@FALSE Then Break BinaryEodSet(filebuf,maxsize) ; Gets binary data from a socket recv=sRecvBinary(datasocket,IntControl(42,filebuf,0,0,0),maxsize) If recv==0 Then Continue ; Update Box Title with the Total Number of Bytes Recieved recvbytes=huge_Add(recvbytes,recv) BoxTitle("Total Recv: ":recvbytes:" Bytes From: ":wxGetInfo(2,datasocket):" (Ctrl+Break to Quit)") ; Read Data Until There is No More nextsize=StrReplace(BinaryPeekStr(filebuf,0,7),"?","") While BinaryEodGet(filebuf)>0 udfGetBuffer(filebuf,maxsize,redir,0) EndWhile maxsize=nextsize EndWhile If ret==@FALSE || recv==0 Then Return @FALSE Return @TRUE #EndFunction Return
Article ID: W17626
Filename: File Transfer Using sSendBinary and sRecvBinary.txt
File Created: 2013:01:18:12:57:04
Last Updated: 2013:01:18:12:57:04