Вопрос по теме Сокет.
Есть задача..но уже месяц не могу решить ... Нужно создать многопоточный сервер , и отправлять файлы с клиентов . Такой как отправить файл и многопоточный сервер , это не проблема . Проблема в другом : дело в том что тот файл который нужно передать, постоянно изменяется . По сути идет запись в файл , он соответственно увелич. . Вопрос как мне в процесе записи этого файла передать его по сокету? Тоесть открыть , допустим передать кусок , потом открыть опять , поставить на послед. позицию , и с той позиции читать опять до определенного момента, при этом передавать все на сокет .
TSocket Событие ONWRITE:
| Код | //cs - client socket //pb - progressbar //FS- файл. поток var Buf: array[0..BUF_LEN-1] of Char; Readed: Int64; Writed: Int64; begin if pb.Position=0 then begin Memo1.Lines.Add('Send File Size - '+FormatFloat('#,##0',FS.Size)+' bytes'); Writed := FS.Size; Socket.SendBuf(Writed,8); Memo1.Lines.Add('Start send File'); end; while pb.Position<=pb.Max do begin Application.ProcessMessages; Readed := FS.Read(Buf[0],BUF_LEN); //читаем файл if Readed=0 then begin pb.Position :=FS.Position; Memo1.Lines[Memo1.Lines.Count-1] := 'Transferred '+ FormatFloat('#,##0',pb.Position)+' bytes'; cs.Close; Form1.t_reload.Enabled:=True; Exit; end; Writed := Socket.SendBuf(Buf[0],Readed); if Writed=-1 then begin Label1.Caption := IntToStr(StrToInt(Label1.Caption)+1); FS.Position := FS.Position-Readed; Exit; end; if Writed<Readed then FS.Position := FS.Position-Readed+Writed; pb.Position := FS.Position; if pb.Position>pb.Tag then begin pb.Tag := pb.Tag+Trunc(FS.Size/100); Memo1.Lines[Memo1.Lines.Count-1] := 'Transferred '+ FormatFloat('#,##0',pb.Position)+' bytes'; end; end; end;
|
ну и вот принимаем :
| Код | var Buf: array[0..BUF_LEN-1] of Char; Len: Integer; FS: TFileStream; FirstREad: Boolean; begin FS := nil;
FirstRead := True; FStream := TWinSocketStream.Create(ClientSocket, 5000); try FLastTime := GetTickCount; while (not Terminated) and (ClientSocket.Connected) do begin if not FStream.WaitForData(10000) then Continue; Len := FStream.Read(Buf[0],BUF_LEN); Form1.memo1.Lines.Add(IntToStr(Len)); if FirstRead then begin if Len>7 then begin FS := TFileStream.Create('TestFile'+intTostr(random(1000))+'.dat',fmCreate); FS.Write(Buf[8],Len-8); FirstRead := False; end; end else FS.Write(Buf[0],Len); if Len=0 then begin FS.Free; Terminate; ClientSocket.Close; Exit; end;
end; finally FStream.Free; end; end;
|
|