Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program project2;
- {$mode objfpc}{$H+}
- uses
- Classes, SysUtils, lNet, strutils;
- Var
- TEMP_DIR: String = '';
- Function GetJSStr(Const aSource, aIndex: String): String;
- Var
- aPos: Integer;
- Begin
- aPos := Pos('"' + aIndex + '":"', aSource);
- If aPos = 0 Then Exit('');
- aPos := aPos + Length('"' + aIndex + '":"');
- Result := Copy(aSource, aPos, PosEx('"',aSource, aPos) - aPos);
- end;
- Type
- { BClientClass }
- BClientClass = Class
- Private
- bConnection: TLTcp;
- bQuit: boolean;
- bFileStream: TFileStream;
- bFileSize: Integer;
- bFileName: String;
- Procedure ProcessRecieve(aSocket: TLSocket);
- Procedure ProcessCanSend(aSocket: TLSocket);
- Procedure ContinueGetFile(Const aSocket: TLSocket);
- Procedure ContinuePutFile(Const aSocket: TLSocket);
- Procedure StartGetFile(Const aSocket: TLSocket);
- Procedure StartPutFile(Const aSocket: TLSocket);
- Public
- Constructor Build;
- Destructor Burn;
- Procedure Run;
- End;
- // implementation
- Procedure BClientClass.ProcessCanSend(aSocket: TLSocket);
- Begin
- ContinuePutFile(aSocket);
- bConnection.CallAction;
- end;
- Procedure BClientClass.ProcessRecieve(aSocket: TLSocket);
- Var
- aMessage: string;
- aType: String;
- aName: String;
- aSize: Integer;
- Begin
- // Получение запросов и самих файлов выполняется в он receive
- // отправка файлов - в ProcessCanSend
- If Not(bFileStream = nil) Then ContinueGetFile(aSocket)
- Else
- If aSocket.GetMessage(aMessage) > 0 Then
- Begin
- aType := GetJSStr(aMessage, 'type');
- bFileName := GetJSStr(aMessage, 'name');
- bFileSize := StrToIntDef(GetJSStr(aMessage, 'size'), -1);
- Case aType Of
- 'GET': StartGetFile(aSocket);
- 'PUT': StartPutFile(aSocket);
- End;
- End;
- End;
- Procedure BClientClass.ContinueGetFile(Const aSocket: TLSocket);
- Var
- aBuffer: Array[0..2047] Of Byte;
- aCount: Integer;
- aWriteCount: LongInt;
- Begin
- Repeat
- aCount := aSocket.Get(aBuffer, 2048);
- If aCount > 0 Then
- bFileStream.Write(aBuffer, aCount);
- Until (aCount < 2048);
- WriteLn(bFileStream.Size, ':', bFileSize);
- If bFileStream.Size = bFileSize Then
- bQuit := TRUE
- End;
- Procedure BClientClass.ContinuePutFile(Const aSocket: TLSocket);
- Var
- aCount: Integer;
- aBuffer: Array[0..2047] Of Byte;
- aSendCount: Integer;
- aError: Boolean;
- Begin
- Repeat
- aCount := bFileStream.Read(aBuffer, 2048);
- If aCount > 0 Then
- Begin
- aSendCount := aSocket.Send(aBuffer, aCount);
- If Not(aSendCount = aCount) Then
- bFileStream.Seek(aSendCount - aCount, soFromCurrent);
- End;
- Until (aCount < 2048) Or Not(aSendCount = aCount);
- If aCount < 2048 Then bQuit := TRUE;
- End;
- Procedure BClientClass.StartGetFile(Const aSocket: TLSocket);
- Begin
- bFileStream := TFileStream.Create(TEMP_DIR + ExtractFileName(bFileName),
- fmCreate);
- ContinueGetFile(aSocket);
- End;
- Procedure BClientClass.StartPutFile(Const aSocket: TLSocket);
- Begin
- bFileStream := TFileStream.Create(bFileName, fmOpenRead Or fmShareDenyWrite);
- If Not(bFileStream.Size = bFileSize) Then
- Begin
- bFileStream.Free;
- bFileStream := nil;
- bQuit := TRUE;
- Exit;
- End;
- ContinuePutFile(aSocket);
- End;
- Constructor BClientClass.Build;
- Begin
- bConnection := TLTCP.Create(nil);
- bConnection.OnReceive := @ProcessRecieve;
- bConnection.OnCanSend := @ProcessCanSend;
- bConnection.Timeout := 100;
- End;
- Destructor BClientClass.Burn;
- Begin
- If Not(bFileStream = nil) Then bFileStream.Free;
- bConnection.Free;
- End;
- Procedure BClientClass.Run;
- Var
- aRequest: String;
- aType: String;
- aFileName: String;
- Begin
- bQuit := False;
- If bConnection.Connect('localhost', 7447) then
- Begin
- Repeat
- bConnection.CallAction;
- Until bConnection.Connected;
- aType := ParamStr(1);
- aFileName := ParamStr(2);
- Case aType Of
- 'GET':
- aRequest := Format('"type":"GET","name":"%s"', [aFileName]);
- 'PUT':
- With TFileStream.Create(aFileName, fmOpenRead) Do
- Begin
- aRequest := Format('{"type":"PUT","name":"%s","size":"%d"}',
- [aFileName, Size]);
- Free;
- End;
- End;
- bConnection.SendMessage(aRequest);
- End;
- While Not(bQuit) Do
- bConnection.CallAction;
- End;
- Begin
- TEMP_DIR := GetTempDir(FALSE) + 'download/';
- If Not(DirectoryExists(TEMP_DIR)) Then mkdir(TEMP_DIR);
- With BClientClass.Build Do
- Begin
- Run;
- Burn;
- End;
- End.
Advertisement
Add Comment
Please, Sign In to add comment