Internet Direct (Indy) 是開源網路元件庫,Delphi 6 起內建。核心特性:**阻塞式** Socket 調用 — 讀寫操作直到完成才返回,程式碼循序執行,邏輯清晰,易移植至 Linux (Kylix)。
| 特性 | 阻塞式 | 非阻塞式 |
|---|---|---|
| 程式碼風格 | 同步循序 | 事件驅動/狀態機 |
| UI 凍結風險 | 主執行緒呼叫會凍結 | 不凍結 |
| 執行緒適合度 | 極適合放入背景執行緒 | 通常在主執行緒事件迴圈 |
| 跨平台一致性 | 高 (Unix/Linux 原生即阻塞) | 低 |
放入表單、設定 IdleTimeOut (預設 50ms)、OnlyWhenIdle。原理:定期呼叫 Application.ProcessMessages 處理訊息,同時保持阻塞調用堆疊不變。
// 表單上放置 TIdAntiFreeze1,無需程式碼即可生效
// 亦可手動建立
var
AntiFreeze: TIdAntiFreeze;
begin
AntiFreeze := TIdAntiFreeze.Create(Self);
AntiFreeze.IdleTimeOut := 20; // ms
AntiFreeze.OnlyWhenIdle := True;
end;
TIdTCPServer 建立監聽執行緒,Accept 後為每個客戶端建立 TIdPeerThread (或執行緒池 TIdThreadMgrPool)。OnExecute 事件在該客戶端執行緒內反覆觸發,直到斷線。AThread.Synchronize 或 TThread.Queue。procedure TFormServer.IdTCPServerExecute(AThread: TIdPeerThread);
var
Cmd: string;
begin
with AThread.Connection do
begin
Cmd := ReadLn; // 阻塞直到收到 CR+LF
AThread.Synchronize(
procedure
begin
ListBoxLog.Items.Add(Format('[%s] %s', [Binding.PeerIP, Cmd]));
end);
if StartsText('DATA ', Cmd) then
begin
FReceivedData := Copy(Cmd, 6, MaxInt);
WriteLn('200 OK');
AThread.Synchronize(UpdateDataDisplay);
end
else if SameText(Cmd, 'QUIT') then
begin
Disconnect;
end
else
WriteLn('500 Unknown Command');
end;
end;
procedure TFormClient.btnConnectClick(Sender: TObject);
begin
IdTCPClient1.Host := edtHost.Text;
IdTCPClient1.Port := StrToInt(edtPort.Text);
try
IdTCPClient1.Connect(5000); // 5 秒逾時
MemoLog.Lines.Add('Connected: ' + IdTCPClient1.IOHandler.ReadLn);
btnSend.Enabled := True;
except
on E: Exception do MemoLog.Lines.Add('Connect failed: ' + E.Message);
end;
end;
procedure TFormClient.btnSendClick(Sender: TObject);
begin
IdTCPClient1.IOHandler.WriteLn('DATA ' + edtData.Text);
MemoLog.Lines.Add('Server: ' + IdTCPClient1.IOHandler.ReadLn);
end;
TIdTCPClient.Connect(Timeout):阻塞連線,逾時拋出例外。IOHandler.ReadLn/WriteLn:行導向讀寫,自動處理 CR+LF。TIdTCPServer.DefaultPort、Active:啟動/停止監聽。AThread.Connection.Socket.Binding.PeerIP:取得客戶端 IP。TIdSSLIOHandlerSocketOpenSSL,指派給 IOHandler,載入 libeay32.dll/ssleay32.dll。TIdThreadMgrPool 限制最大執行緒數,避免連線風暴耗盡資源。TIdCmdTCPServer 宣告式註冊指令處理函數,簡化 OnExecute 邏輯。