線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:7560
推到 Plurk!
推到 Facebook!

求Indy10的TCP Client/Server範例

缺席
gerojeng
一般會員


發表:23
回覆:25
積分:9
註冊:2004-06-19

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-10-09 23:47:25 IP:218.160.xxx.xxx 訂閱
在 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-10-10 16:54:32 IP:218.160.xxx.xxx 訂閱
終於搞定了,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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-10-12 08:07:34 IP:203.75.xxx.xxx 未訂閱
多謝分享唷!
gerojeng
一般會員


發表:23
回覆:25
積分:9
註冊:2004-06-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-10-13 15:38:43 IP:219.70.xxx.xxx 訂閱
繼續,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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-11-11 21:53:44 IP:220.134.xxx.xxx 訂閱
我也覺得Indy應該要出書才行
很多東西不看書光看說明有時會覺得不那麼明白
所以我也支持趕快出吧!!
2007
中階會員


發表:54
回覆:90
積分:98
註冊:2008-08-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-11-12 08:30:29 IP:60.249.xxx.xxx 未訂閱

大大可以提供 範例檔,以供學習嗎?? 謝謝!!

===================引 用 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 那邊處理






系統時間:2024-04-20 15:10:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!