在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

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

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

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

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

    4.1 Lazarus Logger

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

    TEventLog 的主要屬性:

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

    TEventLog 的主要方法:

    方法

    說(shuō)明

    Log()

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

    Warning()

    記錄警告消息

    Error()

    將錯(cuò)誤消息記錄

    Debug()

    記錄調(diào)試消息

    Info()

    記錄信息性消息

    4.2 Tcp Socket 服務(wù)端

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

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

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

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

    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è)置的類(lèi)名的類(lèi)代碼,其中:

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

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

    private TcpServer: TIdTCPServer; Logger: TEventLog;

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

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

    實(shí)現(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;

    實(shí)現(xiàn)客戶端建立連接、斷開(kāi)連接、發(fā)生異常時(shí)觸發(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 // 斷開(kāi)連接 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-水平坐標(biāo), Y-垂直坐標(biāo), E-結(jié)束 Desc: String[16]; // 描述 Value: Integer; // 數(shù)據(jù)值 end;

    實(shí)現(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ā)送水平坐標(biāo) CommBlock.Part:=’X’; CommBlock.Desc:=’水平坐標(biāo)’; CommBlock.Value:=X; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送垂直坐標(biāo) CommBlock.Part:=’Y’; CommBlock.Desc:=’垂直坐標(biāo)’; CommBlock.Value:=Y; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送結(jié)束標(biāo)志 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;

    實(shí)現(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;// 啟動(dòng) 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-水平坐標(biāo), Y-垂直坐標(biāo), 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 // 斷開(kāi)連接 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ā)送水平坐標(biāo) CommBlock.Part:=’X’; CommBlock.Desc:=’水平坐標(biāo)’; CommBlock.Value:=X; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送垂直坐標(biāo) CommBlock.Part:=’Y’; CommBlock.Desc:=’垂直坐標(biāo)’; CommBlock.Value:=Y; OutputInfoLog(‘Send – ‘ + Host + ‘ ‘ + CommBlock.Desc + ‘: ‘ + inttostr(CommBlock.Value)); AContext.Connection.IOHandler.Write(RawToBytes(CommBlock, SizeOf(CommBlock))); // 發(fā)送結(jié)束標(biāo)志 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.

    程序運(yùn)行效果:

    [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 水平坐標(biāo): 550 [2022-06-25 10:30:31.797 Info] 2022-06-25 10:30:31:797 -info- Send – 127.0.0.1 垂直坐標(biāo): 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 水平坐標(biāo): 777 [2022-06-25 10:30:41.794 Info] 2022-06-25 10:30:41:794 -info- Send – 127.0.0.1 垂直坐標(biāo): 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 水平坐標(biāo): 271 [2022-06-25 10:30:51.792 Info] 2022-06-25 10:30:51:792 -info- Send – 127.0.0.1 垂直坐標(biāo): 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 // 斷開(kāi)連接 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)修改,實(shí)現(xiàn)業(yè)務(wù)邏輯即可。

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

    相關(guān)推薦

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

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

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

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

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

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

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

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

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

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

      2022年11月25日
    • 全國(guó)薪資水平報(bào)告2022(全國(guó)平均工資標(biāo)準(zhǔn)2022)

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

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

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

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

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

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

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

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

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

      2022年11月23日

    聯(lián)系我們

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