indy IdTCPServer的一个疑问(100分)

  • 主题发起人 主题发起人 masm
  • 开始时间 开始时间
M

masm

Unregistered / Unconfirmed
GUEST, unregistred user!
在Form1中放入IDTCPServer控件,一旦有socket连接,IDTCPServer自动建立一个线程与之建立一个TCP/IP连接,我们在IDTCPServer.OnExecute中写入自己的代码就可以在这个独立的线程中完成我们所希望的动作吗?因为我看到的函数是TForm1.IdTCPServer1Execute(...);难道这个不是子线程,而是主线程了???
还有如果我们在OnExecute中调用TForm1.aaa这个函数,那么这个函数是不是会造成同步问题,例如登录人数的统计。
 
大家都没考虑过?!
 
>>一旦有socket连接,IDTCPServer自动建立一个线程
--错,应该是:一旦有socket连接,TIdListenerThread.Run自动新建一个IDPeerThread,请看TdListenerThread的源码
>>难道这个不是子线程,而是主线程了???
--同上题
>>同步问题?
--这个就要自己去想办法了,什么事情都帮你做了,那还要你干什么?!
 
谢谢!
第二个问题我还有点不明白
TForm1.IdTCPServer1Execute(...);说明是TForm1类的函数,而我看Demo觉得应当是
IDTCPServer.Execute,这样理解对不对?!
 
以前也有人问过这个问题,没人解决,高手们都过年去了么?!
 
仔细看看代码就知道了,TForm1.IdTCPServer1Execute(...)是在创建的线程里执行的!里面需要自己考虑线程安全问题。
 
提前
希望更多的人参与讨论!!
 
尝试解答你的疑问:
问题一:
在Form1中放入IDTCPServer控件,一旦有socket连接,IDTCPServer自动建立一个线程与之
建立一个TCP/IP连接,我们在IDTCPServer.OnExecute中写入自己的代码就可以在这个独立
的线程中完成我们所希望的动作吗?
解答:
一旦有socket连接,IDTCPServer 不仅建立一个线程,更需要把这个建立的线程保存到一个
线程列表中去。然后在 IDTCPServer.OnExecute 中传入“每线程”这个参数,程序从传入
的“每线程”这个参数,检索出对应的 socket 连接。

问题二:
如果我们在OnExecute中调用TForm1.aaa这个函数,那么这个函数是不是会造成同步问题,
例如登录人数的统计。
解答:
统计登录人数不应该在这个事件中处理。其实只要读一下线程列表就可以知道结果。OnExecute
中的同步,是 indy 的一个工作要求,同时发生的客户必须排队处理。所以,原则上不会
造成同步问题,但是,如果你引用的 Form 过程中,有异步变量,就要注意可能的同步问题。

不知道这样的回答,是否能让你满意。
 
谢谢小雨哥的回答,但是还有一点:IDTCPServer.OnExecute这个过程不存在啊,只有TForm1.IdTCPServer1Execute(...);怎么变成主线程所有了??
 
呵呵。指的应该就是 IdTCPServer1Execute。我交叉引用了你帖子里的称呼,出现了误解。
 
楼主对线程跟类的概念混淆了,应该好好看看DELPHI5从入门到精通,里面有线程也有类的概念阐述,另外再写两个线程类就应该明白了
 
我弄错了??请看下面的代码:
type
TfmClient = class;
TReceiveThread = class(TThread)
private
FMsg : String;
FForm : TfmClient;
...


procedure TReceiveThread.Execute;//线程运行,注意前缀TReceiveThread
begin
while not Terminated do
begin
if FForm.IdTCPClient1.Connected then//IdTCPClient1在FForm这个主线程中
begin
...
怎么解释?!
 
大伙给我瞧瞧,拉兄弟一把哦!
 
您是不是不要这样理解:
“FForm.IdTCPClient1.Connected then // IdTCPClient1 在 FForm 这个主线程中”
您可以理解为:IdTCPClient1 是类实例 FForm 的一个成员。至于您的 TReceiveThread
中引用了 FForm 这个类,并把这个 FForm 类做为了 TThread 类的成员就值得考虑了。
按你描述的意思,大概这个 TfmClient 是一个 TForm 类,这时候除非你动态在线程里创建
这个 TfmClient 类,不然的话就可能有苦头吃了,很容易造成死锁。
 
已经说了,Indy 是一个多线程控件,在 Server 连接的时候,针对每客户会创建一个线程,
只要有客户发送数据,就会激活 Srever 的 OnExecute 事件。需要做的,就是在 OnExecute
中识别是哪个客户(也即线程)发来的请求,针对这个客户的 socket 连接返回服务就可以
了。
Server 端首先是响应客户的 Connect 事件,一旦连接了,就自动在服务端建立了一个连接
线程。而这个连接线程是需要 Server 维护的,indy 的最大连接线程数不会大于 600 个,
有 600 个线程你还不够用的话,基本上就不能使用 indy 控件了。
 
谢谢!
这样理解不知道可不可以?
TForm1.IdTCPServer1Execute(...)其实是在每个单独的server线程中执行的,相互独立。凡是要单独作用的函数要全部写在TForm1.IdTCPServer1Execute(...)中,否则只能顺序执行主线程中的函数,大大降低了效率...
TForm1.IdTCPServer1Execute(...)中能单独写个函数和过程么?
 
我没太看懂你上面说的具体含义,感觉有点对路了,却又似乎不太对。
我试着不考虑你的说法,自己解释一次,你看看有没有帮助:
TForm1.IdTCPServer1Execute(每线程) 是每一个客户端与服务端发生数据传送时都会执行
的,服务端始终处于侦听状态,当侦听到客户请求以后,就把这个客户请求做为参数送入
执行方法,也就是上面的“每线程”。一个服务端可以应付很多客户端的连接请求,但在
同一时刻,由于 indy 设计的缘故,始终只能响应一个客户的请求,其他客户只好排队等候
处理。这时候服务端可以对这个传入的“客户”进行单独处理,也可以向全部的连接的客户
做广播处理,但是,服务端其实唯一知道的只有这个传入的客户,它即便做广播时,也只是
假设全部客户连接都是完好的(服务端维护着全部连接客户的一个列表),唉,不说了,越说
越离题了。呵呵,自己再研究研究吧。
 
啊????
排队等候处理,这不就是异步模式了么???
indy多线程的优势呢??
 
越来越摸不着头脑了...
郁闷啊![:(]
 
后退
顶部