indy高手进来看看..(20分)

  • 主题发起人 主题发起人 zjwzcqd
  • 开始时间 开始时间
Z

zjwzcqd

Unregistered / Unconfirmed
GUEST, unregistred user!
看了一下indy的demo中的chat(聊天室)的例子,发现它的客户端用了timer控件来处理接收数据,
这样界面重画都反应不过来,后来放上了dAntiFreeze好了一些,但还是很慢。
问题:
1.由于chat中服务端有时发送数据是广播的,客户端无法知道数据任时出来,所以它用了timer,
有没有不用timer的方法?
2.用timer时某一时间接收一次,会不会出现有数据没有接受到的可能?
 
既然是聊天室,干吗不用NMUDP1或ClintSocket、SeverSocket
 
indy太垃圾了 问题多多

建议你别用了
 
to songmk INDY有什么垃圾?
to zjwzcqd 你建立一个线程循环读取缓冲区中的内容。不用timer
 
to chengjp
 能否具体一点,给点代码示例.非常感谢!
 
procedure ThreadConnect.Execute;
var s:string;
buf:array[0..2047] of char
begin
// try
while not (Terminated ) and form1.IdTCPClient1.Connected do
begin
form1.IdTCPClient1.ReadBuffer(buf,sizeof(buf));
s:=buf;
if s<>'' then
begin
//处理消息
end;
end;
 
indy 垃圾的地方太多
经常死锁 自己好好用用就知道了 indy都9.0居然还这么多bug 不可思议
 
indy还是可以的,请问 ReadBuffer读了以后,再用readln还读得到吗?(也就是ReadBuffer读了以后会不会clear buffer中的内容.谢谢!
 
从长远考虑还是放弃indy吧
 
to dfw1001,为什么?请兄弟说个明白
 
呵呵,居然有人说indy垃圾多。
indy是我第一个弃用GUI单元的网络通信组件。
而且每个单元都细分,这样编译出来的,就很少有垃圾了,假如你认真选用indy组件的话。

indy死锁,是因为它采用的是多线程的工作方式,如果你用win2000作操作系统,
挂的机会就会大大减少。
 
unit MainForm;

interface

uses
Windows, Messages, Graphics, Controls, Forms, Dialogs, ToolWin, ComCtrls,
Menus, Buttons, Spin, SysUtils, Classes, IdBaseComponent,
IdComponent, IdTCPConnection, IdTCPClient, ExtCtrls, StdCtrls,
IdAntiFreezeBase, IdAntiFreeze, IdIntercept;

type
TDLoadDirThread = class(TThread)
private
msg:string;
TheTCPClient :TIdTCPClient;
protected
procedure Execute; override;
procedure addmemLines;
procedure addc;
public
constructor Create(IdTCPClient:TIdTCPClient);
destructor Destroy; override;
end;

TForm1 = class(TForm)
Label1: TLabel;
edUserName: TEdit;
Label2: TLabel;
edServer: TEdit;
Label3: TLabel;
lbClients: TListBox;
Label4: TLabel;
memLines: TMemo;
Label5: TLabel;
edMessage: TEdit;
SpeedButton1: TSpeedButton;
IdTCPClient1: TIdTCPClient;
Timer1: TTimer;
Label6: TLabel;
sePort: TSpinEdit;
Button1: TButton;
IdAntiFreeze1: TIdAntiFreeze;
IdConnectionIntercept1: TIdConnectionIntercept;
Button2: TButton;
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure IdTCPClient1Connected(Sender: TObject);
procedure edMessageKeyPress(Sender: TObject; var Key: Char);
procedure Button1Click(Sender: TObject);
procedure IdConnectionIntercept1Receive(
ASender: TIdConnectionIntercept; AStream: TStream);
procedure IdConnectionIntercept1Connect(
ASender: TIdConnectionIntercept);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
CT:TDLoadDirThread;
public
{ Public declarations }
end;


var
Form1: TForm1;

implementation

{$R *.DFM}

constructor TDLoadDirThread.Create(IdTCPClient:TIdTCPClient);
begin
inherited Create(True);
TheTCPClient :=IdTCPClient;
Execute;
// FreeOnTerminate :=False;
end;

procedure TDLoadDirThread.addmemLines;
begin
form1.memLines.Lines.Add(Msg);
end;
procedure TDLoadDirThread.addc;
begin
form1.lbClients.Items.CommaText := Msg;
end;
procedure TDLoadDirThread.Execute;
var com,s:string;
buf:array[0..2047] of char ;
begin
// try
while not (Terminated ) and TheTCPClient.Connected do
begin
TheTCPClient.ReadBuffer(buf,sizeof(buf));
s:=buf;
if s<>'' then
begin
//处理消息
Msg:=s;
if Msg[1] <> '@' then
begin
{ Not a system command }
self.Synchronize(addmemLines);
end
else
begin
{ System command }
Com := UpperCase(Trim(Copy(Msg, 2, Pos(':', Msg) -2)));
Msg := UpperCase(Trim(Copy(Msg, Pos(':', Msg) +1, Length(Msg))));
if Com = 'CLIENTS' then
self.Synchronize(addc);
end;

end;
end;
end;
destructor TDLoadDirThread.Destroy;
begin
inherited destroy;
end;


procedure TForm1.FormShow(Sender: TObject);
begin
width := width + 1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
Com,
Msg : String;
begin
// exit;
if not IdTcpClient1.Connected then
exit;
// if not (IdTCPClient1.ReadFromStack(false, 10, false)>0) then exit;
Msg := IdTCPClient1.ReadLn('', 5);

if Msg <> '' then
if Msg[1] <> '@' then
begin
{ Not a system command }
memLines.Lines.Add(Msg);
end
else
begin
{ System command }
Com := UpperCase(Trim(Copy(Msg, 2, Pos(':', Msg) -2)));
Msg := UpperCase(Trim(Copy(Msg, Pos(':', Msg) +1, Length(Msg))));
if Com = 'CLIENTS' then
lbClients.Items.CommaText := Msg;
end;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if (edUserName.Text <> '') and
(edServer.Text <> '') and
SpeedButton1.Down then
begin
IdTCPClient1.Host := edServer.Text;
IdTCPClient1.Port := sePort.Value;
if SpeedButton1.Down then
begin
IdTCPClient1.Connect;
end;
end
else
begin
if (edUserName.Text = '') or
(edServer.Text = '') then
ShowMessage('You must put in a User Name and server name to connect.');
SpeedButton1.Down := false;
end;


end;

procedure TForm1.IdTCPClient1Connected(Sender: TObject);
begin
IdTCPClient1.WriteLn(edUserName.Text);
end;

procedure TForm1.edMessageKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
IdTCPClient1.WriteLn(edMessage.Text);
edMessage.Text := '';
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
IdTCPClient1.WriteLn('@' + 'CLIENTS:REQUEST');
end;

procedure TForm1.IdConnectionIntercept1Receive(
ASender: TIdConnectionIntercept; AStream: TStream);
begin
showmessage('aaa');
end;

procedure TForm1.IdConnectionIntercept1Connect(
ASender: TIdConnectionIntercept);
begin
//showmessage('aaaaaaaa');
CT:=TDLoadDirThread.create(IdTcpClient1);

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ct.Terminate;
IdTCPClient1.Disconnect;
end;

end.


现在把原来的代码修改了一下,但是退出的时候线程关闭出错,信息是收到了,但无法在memo 上显示,开避了一个线程以后,在edit中输入都感到有点吃力,请大家再帮我看看,谢谢!
 
可以建立一个线程,用来读接受到的数据,注意在每次读完的时候SLEEP(0)一下,以证明
你有让时间的想法。
 
各位请帮帮我,帮我看一下上面的代码,// try
while not (Terminated ) and TheTCPClient.Connected do
begin
TheTCPClient.ReadBuffer(buf,sizeof(buf));
s:=buf;
if s<>'' then
begin
//处理消息
Msg:=s;
if Msg[1] <> '@' then
begin
{ Not a system command }
self.Synchronize(addmemLines);
end
else
begin
{ System command }
Com := UpperCase(Trim(Copy(Msg, 2, Pos(':', Msg) -2)));
Msg := UpperCase(Trim(Copy(Msg, Pos(':', Msg) +1, Length(Msg))));
if Com = 'CLIENTS' then
self.Synchronize(addc);
end;
1。是执行的部分,为什么收不到数据。
2。关闭连接时进程怎么关闭.
 
我建议用 TClientSocket比TIdTCPClient好控制多了.
 
Indy10用的是纤程,一种类线程的模式,又不是线程,一个线程可以有几个纤程,据说不太稳定,要感兴趣的朋友可以去下一个看看, 代码写的很不错,据说他还支持IOCP,可惜我扫描整个代码部分,没有发现使用完成端口的代码,估计是下一个版本才有。
 
到底是ics好一点还是indy好一点
 
我认为ICS在做纯WINDOWS下的程序好一点,他用的是消息异步模式。
Indy是线程模式,有的时候容易组塞掉,如果多线程不熟悉还是不用
他的好。
 
张无忌:有没有Ics的资料,我看了它带的帮助不详细,demo也不多,能不能发点资料给我。
zjwzcqd@163.com
thnks!
 
ICS使用比较简单,基本上看他的DEMO就可以应付问题,你看他的DEMO的时候注意看他是在
那些事件里写代码,一般是DataAvailable事件里接收数据,发送数据他提供的方法很多,不过都可以用sendbuffer什么的代替.
 
后退
顶部