求Indy10的TCP Client/Server範例 |
缺席
|
gerojeng
一般會員 發表:23 回覆:25 積分:9 註冊:2004-06-19 發送簡訊給我 |
在 Indy 9 有一個 TCP client/server 的範例,不知道該如何升級到 indy 10
原本 TCommBlock = record // the Communication Block used in both parts (Server Client) Command : string[25]; Msg : string[100]; // name of receiver end; 使用 Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true); 把資料送出 但是看 help 發現 indy10 使用 tbytes , tstream 送資料,原先的Code不知道要怎樣改才能夠讓indy 10也可以把整個record送出去 求完整的範例能把那個 indy 9 的example 改寫成 indy 10 的範例 或者,如果同樣的架構在indy10已經不適用了,有更好的範例或者架構也可以 感激不盡 |
gerojeng
一般會員 發表:23 回覆:25 積分:9 註冊:2004-06-19 發送簡訊給我 |
終於搞定了,Indy 10 的 Example 實在是太少了,在不斷的 Google
研究 Indy10 原始碼後,終於搞出一個D2009 indy10可以 work 的架構 Server 部份 : 要手動加上 uses idcontext; 不然compile 不會過 和Indy 9 比起來 TMyContext = class(TIdServerContext) LastAction : TDatetime ; end; 那個 TIdServerContext 是看了indy原始碼才發現繼承對象要改成這個而不是繼承 TIDcontext Server.ContextClass := TMyContext; // <--這樣這一行才會過 Server.context 本身就是 TidthreadList 了,以前Indy 9 那個tcp/ip的範例中多維護的那個ThreadList就不用了 要訪問全部的 client 就這樣 var i : integer ; begin with Server.Contexts.LockList do try for i := 0 to Count - 1 do begin ShowMessage(DAteTimeTostr(TMyContext(Items[i]).LastAction)); // 這邊加上要做的事 end; finally Server.Contexts.UnlockList; // 有多少次locklist, 就要有多少次 unlocklist , 不然程式會掛掉 end; 那個 TCommblock 也別用了,在indy9可以直接 writebuffer, indy10要手動把一個 record 寫入到 TBytes , 太費工了 放棄不用,直接 context.iohandler.readln 或者 context.iohandler.writeln 然後自己 parse 自己定義的指令格式 真的想傳結構,網路上找到的方法 procedure TForm1.btn1Click(Sender: TObject); var pkt: TSMSConnect; buf: TBytes; begin // 填寫pkt pkt.Head.SequenceID := 1000; pkt.Head.CommandID := 119; StrLCopy(pkt.UID, 'I love you ', SizeOf(pkt.UID)); // ... // 準備緩衝區數據 SetLength(buf, SizeOf(TSMSConnect)); Move(pkt, buf[0], SizeOf(TSMSConnect)); tcpClient.Connect; tcpClient.Socket.Write(buf); tcpClient.Disconnect; end; procedure TForm1.tcpServerExecute(AContext: TIdContext); var pkt: PSMSConnect; buf: TBytes; begin SetLength(buf, SizeOf(TSMSConnect)); AContext.Connection.Socket.ReadBytes(buf, SizeOf(TSMSConnect), False); pkt := PSMSConnect(@buf[0]); Assert(pkt.Head.SequenceID = 1000); mmo1.Lines.Add(pkt.UID); end; Client 部份和indy 9差異不大,一般的 read , write 都從 iohandler 那邊處理 |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
gerojeng
一般會員 發表:23 回覆:25 積分:9 註冊:2004-06-19 發送簡訊給我 |
繼續,indy10 你直接 client.iohandler.writeln('我是中文');
只會收到一堆亂碼,解法如下 uses idglobal ; 發訊息 client.ophandler.writeln('我是中文',enUTF8) ; 收訊息 在server的onExecute 事件 var ReadStr :string ; begin ReadStr := acontext.Connection.IOHandler.ReadLn(enUTF8); end; 我記得ktop有indy team的人呀,好像也有計畫出書,若出版社不願意出,願意放example 或者說明的電子檔上來嗎? 摸索的真痛苦 |
EllisSu
一般會員 發表:1 回覆:4 積分:1 註冊:2009-10-26 發送簡訊給我 |
|
2007
中階會員 發表:54 回覆:90 積分:98 註冊:2008-08-12 發送簡訊給我 |
大大可以提供 範例檔,以供學習嗎?? 謝謝!! ===================引 用 gerojeng 文 章=================== 終於搞定了,Indy 10 的 Example 實在是太少了,在不斷的 Google 研究 Indy10 原始碼後,終於搞出一個D2009 indy10可以 work 的架構 Server 部份 : 要手動加上 uses idcontext; 不然compile 不會過 和Indy 9 比起來 ? TMyContext = class(TIdServerContext) ??? LastAction : TDatetime ; ? end; 那個 TIdServerContext 是看了indy原始碼才發現繼承對象要改成這個而不是繼承 TIDcontext Server.ContextClass := TMyContext; // <--這樣這一行才會過 Server.context 本身就是 TidthreadList? 了,以前Indy 9 那個tcp/ip的範例中多維護的那個ThreadList就不用了 要訪問全部的 client 就這樣 var ?i : integer ; begin ?with Server.Contexts.LockList do ? try ? for i := 0 to Count - 1 do ? begin ShowMessage(DAteTimeTostr(TMyContext(Items[i]).LastAction)); // 這邊加上要做的事 ? end; ? finally ? Server.Contexts.UnlockList; // 有多少次locklist, 就要有多少次 unlocklist , 不然程式會掛掉 ? end; 那個 TCommblock 也別用了,在indy9可以直接 writebuffer, indy10要手動把一個 record 寫入到 TBytes , 太費工了 放棄不用,直接 context.iohandler.readln 或者? context.iohandler.writeln 然後自己 parse? 自己定義的指令格式 真的想傳結構,網路上找到的方法 procedure ? TForm1.btn1Click(Sender: ? TObject); var ? ? pkt: ? TSMSConnect; ? ? buf: ? TBytes; begin ? ? // ? 填寫pkt ? ? pkt.Head.SequenceID ? := ? 1000; ? ? pkt.Head.CommandID ? := ? 119; ? ? StrLCopy(pkt.UID, ? 'I ? love ? you ', ? SizeOf(pkt.UID)); ? ? // ? ... ? ? // ? 準備緩衝區數據 ? ? SetLength(buf, ? SizeOf(TSMSConnect)); ? ? Move(pkt, ? buf[0], ? SizeOf(TSMSConnect)); ? ? tcpClient.Connect; ? ? tcpClient.Socket.Write(buf); ? ? tcpClient.Disconnect; end; procedure ? TForm1.tcpServerExecute(AContext: ? TIdContext); var ? ? pkt: ? PSMSConnect; ? ? buf: ? TBytes; begin ? ? SetLength(buf, ? SizeOf(TSMSConnect)); ? ? AContext.Connection.Socket.ReadBytes(buf, ? SizeOf(TSMSConnect), ? False); ? ? pkt ? := ? PSMSConnect(@buf[0]); ? ? Assert(pkt.Head.SequenceID ? = ? 1000); ? ? mmo1.Lines.Add(pkt.UID); end; Client 部份和indy 9差異不大,一般的? read , write 都從 iohandler 那邊處理 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |