Guest User

Untitled

a guest
Jun 7th, 2012
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 4.63 KB | None | 0 0
  1. program project2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Classes, SysUtils, lNet, strutils;
  7.  
  8. Var
  9.   TEMP_DIR: String = '';
  10.  
  11. Function GetJSStr(Const aSource, aIndex: String): String;
  12. Var
  13.   aPos: Integer;
  14. Begin
  15.   aPos := Pos('"' + aIndex + '":"', aSource);
  16.   If aPos = 0 Then Exit('');
  17.   aPos := aPos + Length('"' + aIndex + '":"');
  18.   Result := Copy(aSource, aPos, PosEx('"',aSource, aPos) - aPos);
  19. end;
  20.  
  21. Type
  22.  
  23.   { BClientClass }
  24.  
  25.   BClientClass = Class
  26.   Private
  27.     bConnection: TLTcp;
  28.     bQuit: boolean;
  29.     bFileStream: TFileStream;
  30.     bFileSize: Integer;
  31.     bFileName: String;
  32.     Procedure ProcessRecieve(aSocket: TLSocket);
  33.     Procedure ProcessCanSend(aSocket: TLSocket);
  34.  
  35.     Procedure ContinueGetFile(Const aSocket: TLSocket);
  36.     Procedure ContinuePutFile(Const aSocket: TLSocket);
  37.     Procedure StartGetFile(Const aSocket: TLSocket);
  38.     Procedure StartPutFile(Const aSocket: TLSocket);
  39.   Public
  40.     Constructor Build;
  41.     Destructor Burn;
  42.     Procedure Run;
  43. End;
  44.  
  45. // implementation
  46.  
  47. Procedure BClientClass.ProcessCanSend(aSocket: TLSocket);
  48. Begin
  49.   ContinuePutFile(aSocket);
  50.   bConnection.CallAction;
  51. end;
  52.  
  53. Procedure BClientClass.ProcessRecieve(aSocket: TLSocket);
  54. Var
  55.   aMessage: string;
  56.   aType: String;
  57.   aName: String;
  58.   aSize: Integer;
  59. Begin
  60.   // Получение запросов и самих файлов выполняется в он receive
  61.   // отправка файлов - в ProcessCanSend
  62.   If Not(bFileStream = nil) Then ContinueGetFile(aSocket)
  63.   Else
  64.     If aSocket.GetMessage(aMessage) > 0 Then
  65.       Begin
  66.         aType := GetJSStr(aMessage, 'type');
  67.         bFileName := GetJSStr(aMessage, 'name');
  68.         bFileSize := StrToIntDef(GetJSStr(aMessage, 'size'), -1);
  69.         Case aType Of
  70.           'GET': StartGetFile(aSocket);
  71.           'PUT': StartPutFile(aSocket);
  72.         End;
  73.       End;
  74. End;
  75.  
  76. Procedure BClientClass.ContinueGetFile(Const aSocket: TLSocket);
  77. Var
  78.   aBuffer: Array[0..2047] Of Byte;
  79.   aCount: Integer;
  80.   aWriteCount: LongInt;
  81. Begin
  82.   Repeat
  83.     aCount := aSocket.Get(aBuffer, 2048);
  84.     If aCount > 0 Then
  85.       bFileStream.Write(aBuffer, aCount);
  86.   Until (aCount < 2048);
  87.   WriteLn(bFileStream.Size, ':', bFileSize);
  88.  
  89.   If bFileStream.Size = bFileSize Then
  90.     bQuit := TRUE
  91. End;
  92.  
  93. Procedure BClientClass.ContinuePutFile(Const aSocket: TLSocket);
  94. Var
  95.   aCount: Integer;
  96.   aBuffer: Array[0..2047] Of Byte;
  97.   aSendCount: Integer;
  98.   aError: Boolean;
  99. Begin
  100.   Repeat
  101.     aCount := bFileStream.Read(aBuffer, 2048);
  102.     If aCount > 0 Then
  103.       Begin
  104.         aSendCount := aSocket.Send(aBuffer, aCount);
  105.         If Not(aSendCount = aCount) Then
  106.           bFileStream.Seek(aSendCount - aCount, soFromCurrent);
  107.       End;
  108.   Until (aCount < 2048) Or Not(aSendCount = aCount);
  109.  
  110.   If aCount < 2048 Then bQuit := TRUE;
  111. End;
  112.  
  113. Procedure BClientClass.StartGetFile(Const aSocket: TLSocket);
  114. Begin
  115.   bFileStream := TFileStream.Create(TEMP_DIR + ExtractFileName(bFileName),
  116.     fmCreate);
  117.   ContinueGetFile(aSocket);
  118. End;
  119.  
  120. Procedure BClientClass.StartPutFile(Const aSocket: TLSocket);
  121. Begin
  122.   bFileStream := TFileStream.Create(bFileName, fmOpenRead Or fmShareDenyWrite);
  123.   If Not(bFileStream.Size = bFileSize) Then
  124.     Begin
  125.       bFileStream.Free;
  126.       bFileStream := nil;
  127.       bQuit := TRUE;
  128.       Exit;
  129.     End;
  130.   ContinuePutFile(aSocket);
  131. End;
  132.  
  133. Constructor BClientClass.Build;
  134. Begin
  135.   bConnection := TLTCP.Create(nil);
  136.   bConnection.OnReceive := @ProcessRecieve;
  137.   bConnection.OnCanSend := @ProcessCanSend;
  138.   bConnection.Timeout := 100;
  139. End;
  140.  
  141. Destructor BClientClass.Burn;
  142. Begin
  143.   If Not(bFileStream = nil) Then bFileStream.Free;
  144.   bConnection.Free;
  145. End;
  146.  
  147. Procedure BClientClass.Run;
  148. Var
  149.   aRequest: String;
  150.   aType: String;
  151.   aFileName: String;
  152. Begin
  153.   bQuit := False;
  154.   If bConnection.Connect('localhost', 7447) then
  155.     Begin
  156.       Repeat
  157.         bConnection.CallAction;
  158.       Until bConnection.Connected;
  159.  
  160.       aType := ParamStr(1);
  161.       aFileName := ParamStr(2);
  162.       Case aType Of
  163.         'GET':
  164.           aRequest := Format('"type":"GET","name":"%s"', [aFileName]);
  165.         'PUT':
  166.           With TFileStream.Create(aFileName, fmOpenRead) Do
  167.             Begin
  168.               aRequest := Format('{"type":"PUT","name":"%s","size":"%d"}',
  169.                 [aFileName, Size]);
  170.               Free;
  171.             End;
  172.       End;
  173.       bConnection.SendMessage(aRequest);
  174.     End;
  175.   While Not(bQuit) Do
  176.     bConnection.CallAction;
  177. End;
  178.  
  179. Begin
  180.   TEMP_DIR := GetTempDir(FALSE) + 'download/';
  181.   If Not(DirectoryExists(TEMP_DIR)) Then mkdir(TEMP_DIR);
  182.   With BClientClass.Build Do
  183.     Begin
  184.       Run;
  185.       Burn;
  186.     End;
  187. End.
Advertisement
Add Comment
Please, Sign In to add comment