亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                「12.網(wǎng)絡(luò)編程」4.Linux環(huán)境下Tcp Socket 編程

                4.Linux環(huán)境下Tcp Socket 編程

                在 Linux 環(huán)境下使用 Indy 組件進行 TCP Socket 編程也非常的簡單,一般情況下,Linux 下編寫 TCP Socket 應(yīng)用程序是不需要有 UI 的,所以,今天我們一起來在 Linux 環(huán)境下實現(xiàn)一個 shell 命令行的 TCP Socket 應(yīng)用程序。

                在 Linux 環(huán)境下編寫 Object Pascal 程序,就需要使用 Lazarus 或者 CodeTyphon 了,我們在本節(jié)使用 CodeTyphon 來編寫,同時在 Linux 下編寫 shell 命令行程序,日志系統(tǒng)是不可缺少的,所以,我先介紹 Lazarus 下的日志系統(tǒng)。

                4.1 Lazarus Logger

                在 Lazarus 中, TEventLog 是一個可用于向系統(tǒng)日志發(fā)送消息的組件。如果不存在系統(tǒng)日志(例如在 Windows 95/98 或 DOS 上),則將消息寫入文件。消息可以使用一般的 Log 調(diào)用,或?qū)iT的 Warning、Error、Info或Debug調(diào)用來記錄,這些調(diào)用具有預(yù)定義的事件類型。

                TEventLog 的主要屬性:

                • LogType – 日志類型,取值: ltSystem | ltFile | ItStdErr | ItStdOut
                • FileName – 日志文件名
                • DefaultEventType – 默認事件類型,取值:etCustom | etInfo | etWarning |etError | etDebug
                • AppendContent – 控制是否將輸出附加到現(xiàn)有文件
                • Active – 激活日志機制,取值為布爾型
                • TimeStampFormat – 時間戳字符串的格式

                TEventLog 的主要方法:

                方法

                說明

                Log()

                將消息記錄到系統(tǒng)日志中

                Warning()

                記錄警告消息

                Error()

                將錯誤消息記錄

                Debug()

                記錄調(diào)試消息

                Info()

                記錄信息性消息

                4.2 Tcp Socket 服務(wù)端

                在 Linux shell 下開發(fā) Tcp Socket 服務(wù)端,需要創(chuàng)建一個 Console Application,然后新建的應(yīng)用程序類中編寫代碼。仍然采用上一節(jié)的示例來說明。

                示例:客戶端定時實時檢測所在機器的屏幕分辨率上行到服務(wù)端,服務(wù)端接收到數(shù)據(jù)后,根據(jù)其屏幕分辨率隨機生成一個坐標并下發(fā)給客戶端,客戶端將應(yīng)用程序的窗體位置放置到相應(yīng)的坐標上。

                客戶端代碼仍然是上一節(jié)的代碼,在此不再贅述。

                首先,打開 CodeTyphon,選擇 Project -> New Project,然后選擇 Console Application,設(shè)置 Application class name 和 Title,單擊 Ok,此時生成的代碼如下:

                program Project1;{$mode objfpc}{$H+}uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp { you can add units after this };type { TTcpApplication } TTcpApplication = class(TCustomApplication) protected procedure DoRun; override; public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; end;{ TTcpApplication }procedure TTcpApplication.DoRun;var ErrorMsg: String;begin // quick check parameters ErrorMsg:=CheckOptions(‘h’, ‘help’); if ErrorMsg” then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; // parse parameters if HasOption(‘h’, ‘help’) then begin WriteHelp; Terminate; Exit; end; { add your program here } // stop program loop Terminate;end;constructor TTcpApplication.Create(TheOwner: TComponent);begin inherited Create(TheOwner); StopOnException:=True;end;destructor TTcpApplication.Destroy;begin inherited Destroy;end;procedure TTcpApplication.WriteHelp;begin { add your help code here } writeln(‘Usage: ‘, ExeName, ‘ -h’);end;var Application: TTcpApplication;begin Application:=TTcpApplication.Create(nil); Application.Title:=’Tcp Application’; Application.Run; Application.Free;end.

                生成的代碼為設(shè)置的類名的類代碼,其中:

                • WriteHelp – 輸出幫助信息
                • DoRun – 該程序的主要執(zhí)行代碼

                下面,我們根據(jù)需求來實現(xiàn) Tcp Server 的功能,由于需要在程序執(zhí)行過程中記錄日志,所以先在該類的聲明部分添加日志和 TIdTCPServer 變量,如下代碼:

                private TcpServer: TIdTCPServer; Logger: TEventLog;

                接下來,聲明日志輸出功能和 Tcp Server 需要實現(xiàn)的事件處理功能,對于日志,我們需要輸出消息類數(shù)據(jù)和錯誤類信息,代碼如下:

                procedure OutputInfoLog(Info: String); // 消息日志procedure OutputErrorLog(Error: String); // 錯誤日志procedure ServeExecute(AContext: TIdContext); // 與客戶端交互數(shù)據(jù)procedure ServeConnecte(AContext: TIdContext); // 客戶端建立連接時觸發(fā)procedure ServeDisconnect(AContext: TIdContext); // 客戶端斷開連接時觸發(fā)procedure ServeException(AContext: TIdContext; AException: Exception); // 與客戶端交互發(fā)生異常時觸發(fā)

                實現(xiàn)日志輸出功能:

                procedure TTcpApplication.OutputInfoLog(Info: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -info- ‘ + Info; Writeln(LogContent); Logger.Info(LogContent);end;procedure TTcpApplication.OutputErrorLog(Error: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -error- ‘ + Error; Writeln(LogContent); Logger.Info(LogContent);end;

                實現(xiàn)客戶端建立連接、斷開連接、發(fā)生異常時觸發(fā)的事件:

                procedure TTcpApplication.ServeConnecte(AContext: TIdContext);var Info: String;begin // 連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has created connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeDisconnect(AContext: TIdContext);var Info: String;begin // 斷開連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has closed connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeException(AContext: TIdContext; AException: Exception);var Info: String;begin // 異常 Info := AContext.Connection.Socket.Binding.PeerIP + ‘ ‘ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – Error: ‘ + AException.Message; OutputErrorLog(Info);end;

                定義交互數(shù)據(jù)結(jié)構(gòu):

                // 通信數(shù)據(jù)結(jié)構(gòu) TCommBlock = Record Part: String[1]; // 客戶端上傳: W-屏幕寬度, H-屏幕高度, E-結(jié)束; 服務(wù)端下發(fā): X-水平坐標, Y-垂直坐標, E-結(jié)束 Desc: String[16]; // 描述 Value: Integer; // 數(shù)據(jù)值 end;

                實現(xiàn)數(shù)據(jù)交互功能:

                procedure TTcpApplication.ServeExecute(AContext: TIdContext);var CommBlock: TCommBlock; bytes: TIdBytes; W, H, X, Y: Integer; Host: String;begin // 執(zhí)行 if AContext.Connection.Connected then begin try OutputInfoLog(‘—– Start —–‘); Host:=AContext.Connection.Socket.Binding.PeerIP; AContext.Connection.IOHandler.ReadBytes(bytes, SizeOf(CommBlock), False); BytesToRaw(bytes, CommBlock, SizeOf(CommBlock)); OutputInfoLog(‘Recv – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); if CommBlock.Part = ‘W’ then W:=CommBlock.Value; if CommBlock.Part = ‘H’ then H:=CommBlock.Value; if CommBlock.Part = ‘E’ then begin Randomize; X:=Random(W); Y:=Random(H); // 發(fā)送水平坐標 CommBlock.Part:=’X’; CommBlock.Desc:=’水平坐標’; CommBlock.Value:=X; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送垂直坐標 CommBlock.Part:=’Y’; CommBlock.Desc:=’垂直坐標’; CommBlock.Value:=Y; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送結(jié)束標志 CommBlock.Part:=’E’; CommBlock.Desc:=’結(jié)束’; CommBlock.Value:=0; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); end; except ON E: Exception do OutputErrorLog(‘ERROR: ‘ + Host + ‘ – ‘ + E.Message); end; end;end;

                實現(xiàn)主程序:

                // 日志初始化Logger:=TEventLog.Create(Self);Logger.FileName:=’tcp_serve.log’;Logger.LogType:=ltFile;Logger.DefaultEventType:=etDebug;Logger.AppendContent:=True;Logger.Active:=True;// Server 端初始化TcpServer:=TIdTCPServer.Create(Self);TcpServer.DefaultPort:=8081;// 設(shè)置 Server 端事件處理TcpServer.OnConnect:=@ServeConnecte;TcpServer.OnDisconnect:=@ServeDisconnect;TcpServer.OnExecute:=@ServeExecute;TcpServer.OnException:=@ServeException;// 啟動 ServerTcpServer.StartListening;TcpServer.Active:=True;OutputInfoLog(‘Started at 8081’); while True do readln();// 釋放資源 Logger.Destroy;TcpServer.StopListening;TcpServer.Destroy; // stop program loopTerminate;

                完整代碼如下:

                program ct1203;{$mode objfpc}{$H+}uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp, IdTCPServer, IdContext, IdGlobal, EventLog { you can add units after this };type { TTcpApplication } TTcpApplication = class(TCustomApplication) private TcpServer: TIdTCPServer; Logger: TEventLog; protected procedure DoRun; override; procedure OutputInfoLog(Info: String); procedure OutputErrorLog(Error: String); procedure ServeExecute(AContext: TIdContext); procedure ServeConnecte(AContext: TIdContext); procedure ServeDisconnect(AContext: TIdContext); procedure ServeException(AContext: TIdContext; AException: Exception); public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; // procedure WriteHelp; virtual; end; // 通信數(shù)據(jù)結(jié)構(gòu) TCommBlock = Record Part: String[1]; // 客戶端上傳: W-屏幕寬度, H-屏幕高度, E-結(jié)束; 服務(wù)端下發(fā): X-水平坐標, Y-垂直坐標, E-結(jié)束 Desc: String[16]; // 描述 Value: Integer; // 數(shù)據(jù)值 end;{ TTcpApplication }procedure TTcpApplication.OutputInfoLog(Info: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -info- ‘ + Info; Writeln(LogContent); Logger.Info(LogContent);end;procedure TTcpApplication.OutputErrorLog(Error: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -error- ‘ + Error; Writeln(LogContent); Logger.Info(LogContent);end;procedure TTcpApplication.ServeConnecte(AContext: TIdContext);var Info: String;begin // 連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has created connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeDisconnect(AContext: TIdContext);var Info: String;begin // 斷開連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has closed connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeException(AContext: TIdContext; AException: Exception);var Info: String;begin // 異常 Info := AContext.Connection.Socket.Binding.PeerIP + ‘ ‘ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – Error: ‘ + AException.Message; OutputErrorLog(Info);end;procedure TTcpApplication.ServeExecute(AContext: TIdContext);var CommBlock: TCommBlock; bytes: TIdBytes; W, H, X, Y: Integer; Host: String;begin // 執(zhí)行 if AContext.Connection.Connected then begin try OutputInfoLog(‘—– Start —–‘); Host:=AContext.Connection.Socket.Binding.PeerIP; AContext.Connection.IOHandler.ReadBytes(bytes, SizeOf(CommBlock), False); BytesToRaw(bytes, CommBlock, SizeOf(CommBlock)); OutputInfoLog(‘Recv – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); if CommBlock.Part = ‘W’ then W:=CommBlock.Value; if CommBlock.Part = ‘H’ then H:=CommBlock.Value; if CommBlock.Part = ‘E’ then begin Randomize; X:=Random(W); Y:=Random(H); // 發(fā)送水平坐標 CommBlock.Part:=’X’; CommBlock.Desc:=’水平坐標’; CommBlock.Value:=X; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送垂直坐標 CommBlock.Part:=’Y’; CommBlock.Desc:=’垂直坐標’; CommBlock.Value:=Y; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送結(jié)束標志 CommBlock.Part:=’E’; CommBlock.Desc:=’結(jié)束’; CommBlock.Value:=0; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); end; except ON E: Exception do OutputErrorLog(‘ERROR: ‘ + Host + ‘ – ‘ + E.Message); end; end;end;procedure TTcpApplication.DoRun;// var // ErrorMsg: String;begin // quick check parameters (*ErrorMsg:=CheckOptions(‘h’, ‘help’); if ErrorMsg” then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end;*) // parse parameters (*if HasOption(‘h’, ‘help’) then begin WriteHelp; Terminate; Exit; end;*) { add your program here } Logger:=TEventLog.Create(Self); Logger.FileName:=’tcp_serve.log’; Logger.LogType:=ltFile; Logger.DefaultEventType:=etDebug; Logger.AppendContent:=True; // Logger.TimeStampFormat:=’yyyy-mm-dd hh:nn:ss:zzz’; Logger.Active:=True; TcpServer:=TIdTCPServer.Create(Self); TcpServer.DefaultPort:=8081; TcpServer.OnConnect:=@ServeConnecte; TcpServer.OnDisconnect:=@ServeDisconnect; TcpServer.OnExecute:=@ServeExecute; TcpServer.OnException:=@ServeException; TcpServer.StartListening; TcpServer.Active:=True; OutputInfoLog(‘Started at 8081’); while True do readln(); Logger.Destroy; TcpServer.StopListening; TcpServer.Destroy; // stop program loop Terminate;end;constructor TTcpApplication.Create(TheOwner: TComponent);begin inherited Create(TheOwner); StopOnException:=True;end;destructor TTcpApplication.Destroy;begin inherited Destroy;end;(*procedure TTcpApplication.WriteHelp;begin { add your help code here } writeln(‘Usage: ‘, ExeName, ‘ -h’);end;*)var Application: TTcpApplication;begin Application:=TTcpApplication.Create(nil); Application.Title:=’Tcp Application’; Application.Run; Application.Free;end.

                程序運行效果:

                [2022-06-25 10:30:07.442 Info] 2022-06-25 10:30:07:442 -info- Started at 8081 [2022-06-25 10:30:21.783 Info] 2022-06-25 10:30:21:783 -info- 127.0.0.1:52612 – has created connection. [2022-06-25 10:30:21.783 Info] 2022-06-25 10:30:21:783 -info- —– Start —– [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Recv – 127.0.0.1 寬度: 1920 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- —– Start —– [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Recv – 127.0.0.1 高度: 1080 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- —– Start —– [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Recv – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Send – 127.0.0.1 水平坐標: 550 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Send – 127.0.0.1 垂直坐標: 877 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Send – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- —– Start —– [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Recv – 127.0.0.1 寬度: 1920 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- —– Start —– [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Recv – 127.0.0.1 高度: 1080 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- —– Start —– [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Recv – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Send – 127.0.0.1 水平坐標: 777 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Send – 127.0.0.1 垂直坐標: 950 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Send – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- —– Start —– [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Recv – 127.0.0.1 寬度: 1920 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- —– Start —– [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Recv – 127.0.0.1 高度: 1080 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- —– Start —– [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Recv – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Send – 127.0.0.1 水平坐標: 271 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Send – 127.0.0.1 垂直坐標: 294 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Send – 127.0.0.1 結(jié)束: 0 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- —– Start —– [2022-06-25 10:30:53.792 Info] 2022-06-25 10:30:53:792 -error- ERROR: 127.0.0.1 – Connection Closed Gracefully. [2022-06-25 10:30:53.792 Info] 2022-06-25 10:30:53:792 -info- 127.0.0.1:52612 – has closed connection.

                4.3 Tcp Socket Server 代碼框架

                program 程序名;{$mode objfpc}{$H+}uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp, IdTCPServer, IdContext, IdGlobal, EventLog { you can add units after this };type { TTcpApplication } TTcpApplication = class(TCustomApplication) private TcpServer: TIdTCPServer; Logger: TEventLog; protected procedure DoRun; override; procedure OutputInfoLog(Info: String); procedure OutputErrorLog(Error: String); procedure ServeExecute(AContext: TIdContext); procedure ServeConnecte(AContext: TIdContext); procedure ServeDisconnect(AContext: TIdContext); procedure ServeException(AContext: TIdContext; AException: Exception); public constructor Create(TheOwner: TComponent); override; destructor Destroy; override; end;{ TTcpApplication }procedure TTcpApplication.OutputInfoLog(Info: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -info- ‘ + Info; Writeln(LogContent); Logger.Info(LogContent);end;procedure TTcpApplication.OutputErrorLog(Error: String);var LogContent: String;begin LogContent:=FormatDateTime(‘yyyy-mm-dd hh:nn:ss:zzz’, Now) + ‘ -error- ‘ + Error; Writeln(LogContent); Logger.Info(LogContent);end;procedure TTcpApplication.ServeConnecte(AContext: TIdContext);var Info: String;begin // 連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has created connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeDisconnect(AContext: TIdContext);var Info: String;begin // 斷開連接 Info := AContext.Connection.Socket.Binding.PeerIP + ‘:’ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – has closed connection.’; OutputInfoLog(Info);end;procedure TTcpApplication.ServeException(AContext: TIdContext; AException: Exception);var Info: String;begin // 異常 Info := AContext.Connection.Socket.Binding.PeerIP + ‘ ‘ + inttostr(AContext.Connection.Socket.Binding.PeerPort) + ‘ – Error: ‘ + AException.Message; OutputErrorLog(Info);end;procedure TTcpApplication.ServeExecute(AContext: TIdContext);begin // 執(zhí)行 – 業(yè)務(wù)邏輯 end;procedure TTcpApplication.DoRun;begin { add your program here } Logger:=TEventLog.Create(Self); Logger.FileName:=’tcp_serve.log’; Logger.LogType:=ltFile; Logger.DefaultEventType:=etDebug; Logger.AppendContent:=True; Logger.Active:=True; TcpServer:=TIdTCPServer.Create(Self); TcpServer.DefaultPort:=8081; TcpServer.OnConnect:=@ServeConnecte; TcpServer.OnDisconnect:=@ServeDisconnect; TcpServer.OnExecute:=@ServeExecute; TcpServer.OnException:=@ServeException; TcpServer.StartListening; TcpServer.Active:=True; Writeln(‘Started at 8081’); Logger.Info(‘Started at 8081′); while True do readln(); // stop program loop Terminate;end;constructor TTcpApplication.Create(TheOwner: TComponent);begin inherited Create(TheOwner); StopOnException:=True;end;destructor TTcpApplication.Destroy;begin inherited Destroy;end;var Application: TTcpApplication;begin Application:=TTcpApplication.Create(nil); Application.Title:=’Tcp Application’; Application.Run; Application.Free;end.

                將上面的代碼框架復(fù)制后適當(dāng)修改,實現(xiàn)業(yè)務(wù)邏輯即可。

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年6月27日 15:04
                下一篇 2022年6月27日 15:05

                相關(guān)推薦

                • 凈利潤率越高越好嗎(凈利潤率多少合適)

                  一、持續(xù)增收不增利,平均凈利潤率首次跌入個位數(shù) 2021年,增收不增利依舊是行業(yè)主流。具體來看,大部分企業(yè)營業(yè)收入呈增長態(tài)勢,E50企業(yè)平均同比增速達到17.3%,但是利潤增速則明…

                  2022年11月26日
                • 劉畊宏回應(yīng)梅西輸球后哭了:跳操流汗到眼睛 剛好有點流鼻水

                  11月23日,劉畊宏發(fā)言回應(yīng)自己再梅西輸球后流淚的消息,他寫道:“我是有些難過… 然后…跳操流汗到眼睛,剛好有點流鼻水,阿根廷之后的比賽會贏的!”據(jù)悉,11月22日的世界杯比賽中,…

                  2022年11月26日
                • EDG粉絲酸了!JDG重磅官宣,頂級打野Kanavi留在LPL賽區(qū)

                  2022英雄聯(lián)盟職業(yè)聯(lián)賽冬季轉(zhuǎn)會期已經(jīng)于11月22日拉開帷幕,在轉(zhuǎn)會期首日作為LPL觀眾關(guān)注的焦點的JDG戰(zhàn)隊,就官宣了Yagao離隊以及Homme續(xù)約的消息,這讓人十分意外。畢竟…

                  2022年11月25日
                • 2022世界杯比賽什么時候結(jié)束總共幾天(2022世界杯比賽對陣圖)

                  2022年卡塔爾世界杯吸引無數(shù)用戶關(guān)注,大家每天也都第一時間觀看世界杯的比賽情況。那么,2022世界杯比賽什么時候結(jié)束?本屆世界杯比賽總共幾天時間呢?很多網(wǎng)友對于2022年世界杯時…

                  2022年11月25日
                • 賈乃亮的消息的最新動態(tài)(賈乃亮終于又宣布好消息)

                  本以為賈乃亮與李小璐官宣離婚后的畫風(fēng),該是“一別兩寬,各生歡喜”。 誰知卻是“剪不斷,理還亂”,八卦傳聞比離婚前還多。 最近,就有不少新聞報道稱,賈乃亮和李小璐又決定為了女兒復(fù)合?!?/p>

                  2022年11月25日
                • 全國薪資水平報告2022(全國平均工資標準2022)

                  今年5月,國家統(tǒng)計局公布了官方權(quán)威的2021年各行業(yè)平均工資,2021年,全國城鎮(zhèn)非私營單位就業(yè)人員年平均工資為106837元;全國城鎮(zhèn)私營單位就業(yè)人員年平均工資為62884元。 …

                  2022年11月25日
                • 修瑪坐標(瑪修 百科)

                  本文主要講的是修瑪坐標,以及和瑪修 百科相關(guān)的知識,如果覺得本文對您有所幫助,不要忘了將本文分享給朋友。 LR的寶寶修馬在哪抓?具體是什么系的?技能又該怎么學(xué)? 獅王休瑪?shù)淖鴺耍?…

                  2022年11月25日
                • 不止《阿凡達》 網(wǎng)傳海賊王新電影《RED》引進大陸:12月1日上映

                  11月23日消息,20世紀影業(yè)官方正式宣布《阿凡達2:水之道》中國內(nèi)地正式定檔,12月16日同步北美上映。 好消息不止一個,據(jù)博主“海賊王公會”爆料:海賊王新劇場版《RED》,中譯…

                  2022年11月24日
                • 今天出入濟南最新通知(出入濟南政策最新消息今天)

                  近日濟南疫情感染人數(shù)也在不斷增加,劃分的高風(fēng)險區(qū)也是越來越多了。據(jù)最新統(tǒng)計,截止2022年11月24日11時,濟南共有低風(fēng)險地區(qū)12處,高風(fēng)險地區(qū)338處。很多朋友都擔(dān)心現(xiàn)在濟南無…

                  2022年11月24日
                • 再見Kanavi?被告上法庭!韓媒爆料:違規(guī)接觸JDG,散布虛假消息

                  最近關(guān)于JDG的轉(zhuǎn)會消息特別多,尤其是在doinb爆料Kanavi大概率和JDG續(xù)約,并且JDG要買下Ruler之后,很多人都期待明年JDG的銀河戰(zhàn)隊可以打出好的成績。但是沒想到最…

                  2022年11月23日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息