本文移植自 Delphi 盒子範例,升級至 Delphi 2009 (Unicode) 版本。Server 採 TIdTCPServer + TIdSchedulerOfThreadPool 執行緒池,支援多客戶端並發。通訊協定採行為導向文字命令:LOGIN、SENDT (文字)、SENDF (檔案)、FILE/SIZE/READY/OK/DONE 檔案傳輸握手。Client 端使用 TTimer 輪詢非阻塞接收。
TUser 類別封裝客戶端狀態:IP、Port、UserName、TIdContext、命令佇列 (TThreadList)、UI 同步鎖TIdTCPServer.OnExecute:輪詢 CheckForDataOnSource(250)、處理輸入文字、從佇列取出命令發送OnConnect/OnDisconnect:建立/銷毀 TUser、UI 列表同步更新 (PostMessage)LargeStream=True、OnWork 事件回報進度、Write(FileStream, Size) 發送TTimer (250ms) 呼叫 CheckForDataOnSource、ReadLn 解析命令ReadInt64 取得大小 → ReadStream 寫入檔案 → 回覆 OKOnWork 事件
Connection.IOHandler.WriteLn(Format('FILE %s', [ExtractFileName(FileName)]));
Str := Connection.IOHandler.ReadLn;
if SameText(Str, 'SIZE') then begin
FStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
Connection.IOHandler.Write(ToBytes(FStream.Size)); // 發送 8 位元組大小
Str := Connection.IOHandler.ReadLn;
if SameText(Str, 'READY') then begin
Connection.IOHandler.LargeStream := True;
Connection.OnWork := AUser.DoWork; // 進度回呼
AUser.FWorkSize := FStream.Size;
Connection.IOHandler.Write(FStream, FStream.Size);
Connection.OnWork := nil;
Connection.IOHandler.LargeStream := False;
end;
end;
FSize := IdTCPClient.IOHandler.ReadInt64(False);
pbProgress.Max := FSize;
IdTCPClient.IOHandler.WriteLn('READY');
FStream := TFileStream.Create(SaveFileName, fmCreate);
IdTCPClient.IOHandler.LargeStream := True;
IdTCPClient.IOHandler.ReadStream(FStream, FSize);
IdTCPClient.IOHandler.LargeStream := False;
IdTCPClient.IOHandler.WriteLn('OK');
enUTF8 編碼TIdSchedulerOfThreadPool 需在 uses 引用 IdSchedulerOfThreadPool完整原始碼 (Server/Client 兩個專案) 可至原文連結下載。此範例展示 Indy 10 實作生產級 TCP 應用的完整模式。