最近在用indy 10.5.5版本的 IdTcpServer 及 IdTcpClient做开发,整个过程很不顺利,官方没demo,网上的一些demo又过于简单。
困惑1:
客户端每次和服务端通讯完成后立即断开IdTCPClient.Disconnect这样没问题,但如果服务端主动断开客户端AContext.Connection.Disconnect,运行几次就会出问题。不知道为什么? 客户端和服务端是不是每次完成通讯后都必须Disconnect?那为什么服务端主动Disconnect会出问题?困惑2:
客户端可能会并行几个任务,所以我是每次需要通讯时动态创建一个IdTCPClient,用完后Free。这样做好吗?困惑3:
关于通讯的问题,我现在的做法是在一个过程中完成多次通讯,不知这样做是否正确?请看下面的代码。。代码及流程图如下:客户端 服务端
|------> |
| |
| <------|
| |
|------> |
| |
| <------|
客户端代码:procedure TForm1.Button1Click();
var
aClient: TIdTCPClient;
str: string;
begin
//创建及连接代码在此省略。 aClient.IOHandler.WriteLn('1');
str := aClient.IOHandler.ReadLn;
//在此做一些处理...... aClient.IOHandler.WriteLn('2');
str := aClient.IOHandler.ReadLn;
//在此做一些处理...... //断开
end;
服务端代码:procedure TForm1.ServerExecute(AContext: TIdContext);
var
str: string;
begin
str := AContext.Connection.IOHandler.ReadLn;
//在此做一些处理......
AContext.Connection.IOHandler.WriteLn('1'); str := AContext.Connection.IOHandler.ReadLn;
//在此做一些处理......
AContext.Connection.IOHandler.WriteLn('2');
//在此并不做断开,否则运行一段时间就会出现一些死连接,不知为什么。。?
end;
困惑1:
客户端每次和服务端通讯完成后立即断开IdTCPClient.Disconnect这样没问题,但如果服务端主动断开客户端AContext.Connection.Disconnect,运行几次就会出问题。不知道为什么? 客户端和服务端是不是每次完成通讯后都必须Disconnect?那为什么服务端主动Disconnect会出问题?困惑2:
客户端可能会并行几个任务,所以我是每次需要通讯时动态创建一个IdTCPClient,用完后Free。这样做好吗?困惑3:
关于通讯的问题,我现在的做法是在一个过程中完成多次通讯,不知这样做是否正确?请看下面的代码。。代码及流程图如下:客户端 服务端
|------> |
| |
| <------|
| |
|------> |
| |
| <------|
客户端代码:procedure TForm1.Button1Click();
var
aClient: TIdTCPClient;
str: string;
begin
//创建及连接代码在此省略。 aClient.IOHandler.WriteLn('1');
str := aClient.IOHandler.ReadLn;
//在此做一些处理...... aClient.IOHandler.WriteLn('2');
str := aClient.IOHandler.ReadLn;
//在此做一些处理...... //断开
end;
服务端代码:procedure TForm1.ServerExecute(AContext: TIdContext);
var
str: string;
begin
str := AContext.Connection.IOHandler.ReadLn;
//在此做一些处理......
AContext.Connection.IOHandler.WriteLn('1'); str := AContext.Connection.IOHandler.ReadLn;
//在此做一些处理......
AContext.Connection.IOHandler.WriteLn('2');
//在此并不做断开,否则运行一段时间就会出现一些死连接,不知为什么。。?
end;
解决方案 »
- 一个程序设置了俩窗体 form1(主)form2(次),form1最小化,form2也最小化了,怎么让form2没反映?
- 如何手动创建reportbuilder的控件?
- 提示Class TXMLTransform没找到,怎么办
- select 日期 from 表单1后的问题请问如何实现呀? 高手帮忙呀!!!!!
- 这段程序怎么不对了 我改不了 很急
- 初学delphi者问题:[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'
- 关于内存文件映射与流的读写
- 请问spinEdit组件在哪里?
- 命苦的人问问各位工作状况,看看自己离真正的程序员还有多远(恳请版主不要删除此贴)
- 接着散分,up有分
- DELPHI下对WORD操作的紧急求助,各路大侠救命!
- 用delphi设计类似于word里面的“打开”功能,并在memo中显示打开文件的内容
对indy玩的不多。原本只习惯于直接 socket api。
在连接前,先断开连接。这样可能会少几次报错。
http://www.pudn.com/downloads122/sourcecode/p2p/detail519196.html
DNS : String[20]; { Hostname }
Connected, { Time of connect }
LastAction : TDateTime; { Time of last transaction }
Thread : Pointer; { Pointer to thread }
end; PClient = ^TClient;procedure TFormMain.TCPServerConnect(AThread: TIdPeerThread);
var
NewClient: PClient;
begin
GetMem(NewClient, SizeOf(TClient)); NewClient.DNS := AThread.Connection.LocalName;
NewClient.Connected := Now;
NewClient.LastAction := NewClient.Connected;
NewClient.Thread := AThread; AThread.Data:=TObject(NewClient); try
Clients.LockList.Add(NewClient);
finally
Clients.UnlockList;
end;
end;procedure TFormMain.TCPServerDisconnect(AThread: TIdPeerThread);
var
ActClient: PClient;
begin
ActClient := PClient(AThread.Data);
try
Clients.LockList.Remove(ActClient);
finally
Clients.UnlockList;
end;
FreeMem(ActClient);
AThread.Data := nil;
end;procedure TFormMain.TCPServerExecute(AThread: TIdPeerThread);
var
ActClient, RecClient: PClient;
RecThread: TIdPeerThread;
begin
if not AThread.Terminated and AThread.Connection.Connected then begin
with Clients.LockList do begin
try
for i := 0 to Count-1 do begin// iterate through client-list
RecClient := Items[i]; // get client-object
RecThread := RecClient.Thread; // get client-thread out of it
iLen := RecThread.Connection.ReadFromStack(false, 20, false);
end;
do something...
finally
Clients.UnlockList;
end;
end;
end;
end;
begin
TcpServer.Active := False;
Clients.Free;
Release;
end;