请教Indy9和Indy10的问题.一个很简单的TCP连接的程序.我用Indy9可以执行成功.换到Indy10以后,相同的写法,却老是连不上Server,变化有

  • 主题发起人 主题发起人 GalfordLiu
  • 开始时间 开始时间
G

GalfordLiu

Unregistered / Unconfirmed
GUEST, unregistred user!
请教Indy9和Indy10的问题.一个很简单的TCP连接的程序.我用Indy9可以执行成功.换到Indy10以后,相同的写法,却老是连不上Server,变化有这么大么?(50分)<br />请教Indy9和Indy10的问题.
一个很简单的TCP连接的程序.我用Indy9可以执行成功.换到Indy10以后,相同的写法,却老是连不上Server,变化有这么大么?
不知道为什么Indy10老是连接不上,是不是我那里写错了?
代码如下:
/////////////////////////////////////////////////////
indy9 Delphi7的
/////////////////////////////////////////////////////
服务端
放一个ListBox,一个TIdTCPServer,DefaultPort为6666

unit Server;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer;


type
TfrmServer = class(TForm)
IdTCPServer1: TIdTCPServer;
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmServer: TfrmServer;

implementation

{$R *.dfm}

procedure TfrmServer.FormCreate(Sender: TObject);
begin
IdTCPServer1.Active:=True;
end;

procedure TfrmServer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPServer1.active:=False;
end;

procedure TfrmServer.IdTCPServer1Execute(AThread: TIdPeerThread);
var
LLine:string;
begin
LLine:=AThread.Connection.ReadLn();
ListBox1.Items.Add(LLine);
end;

end.
/////////////////////////////////////////////////////

/////////////////////////////////////////////////////
客户端
放一个Edit,一个Button,一个TIdTCPClient;TIdTCPClient的Host为127.0.0.1,Port为6666

unit Client;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, IdIOHandler, IdIOHandlerStream;

type
TfrmClient = class(TForm)
Edit1: TEdit;
Button1: TButton;
IdTCPClient1: TIdTCPClient;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmClient: TfrmClient;

implementation

{$R *.dfm}

procedure TfrmClient.Button1Click(Sender: TObject);
begin
IdTCPClient1.Connect();
if IdTCPClient1.Connected then
begin
IdTCPClient1.WriteLn(Edit1.Text);
end;
IdTCPClient1.Disconnect;
end;

end.
/////////////////////////////////////////////////////

Indy10 Delphi2006的
/////////////////////////////////////////////////////
服务端
放一个ListBox,一个TIdTCPServer,DefaultPort为6666
/////////////////////////////////////////////////////
unit Server;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer,
IdCustomTCPServer,IdContext;

type
TfrmServer = class(TForm)
IdTCPServer1: TIdTCPServer;
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure IdTCPServer1Execute(AContext: TIdContext);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmServer: TfrmServer;

implementation

{$R *.dfm}

procedure TfrmServer.FormCreate(Sender: TObject);
begin
IdTCPServer1.Active:=True;
end;

procedure TfrmServer.IdTCPServer1Execute(AContext: TIdContext);
var
LLine:string;
begin
LLine:= AContext.Connection.IOHandler.ReadLn;
ListBox1.Items.Add(LLine);
end;

procedure TfrmServer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPServer1.active:=False;
end;

end.
/////////////////////////////////////////////////////
客户端
放一个Edit,一个TIdTCPClient,一个TIdIOHandlerStream,
TIdTCPClient的IOHandler设置为TIdIOHandlerStream,
TIdTCPClient的Host为127.0.0.1,Port为6666
/////////////////////////////////////////////////////
unit Client;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, IdIOHandler, IdIOHandlerStream;

type
TfrmClient = class(TForm)
Edit1: TEdit;
Button1: TButton;
IdTCPClient1: TIdTCPClient;
IdIOHandlerStream1: TIdIOHandlerStream;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmClient: TfrmClient;

implementation

{$R *.dfm}

procedure TfrmClient.Button1Click(Sender: TObject);
begin
IdTCPClient1.Connect();
if IdTCPClient1.Connected then
begin
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
end;
IdTCPClient1.Disconnect;
end;

end.
/////////////////////////////////////////////////////

很简单的TCP连接啊,Indy10总是连接不上.难道Indy10还要做什么特殊的设置么?
 
看这里http://www.delphibbs.com/delphibbs/dispq.asp?lid=3529141
 
先謝樓上的.

我試了一下.發現只要加了IOHandler,這樣就會連接不成功.為什麽呢?IOHandler用於做什麽的?

是否一定要用定時器來取得服務器發送過來的信息?有沒有別的方法?服務器向客戶端發送了數據,客戶端不知道嗎?
如果一定只能用Timer,那麽服務器的Execute,是否也是一個輪詢而已?
 
对INDY很失望,BUG特多,我都不敢用了。
组件很多,但基本上没几个用起来可以不出错,跟RFC的出入比较大,小角落里的BUG都没找出来,没做过详细的测试
 
对INDY很失望,BUG特多,我都不敢用了。
 
to pl5th2001
正因为如此,Indy现在已经有2年没有Release新版本了,目前的DevSnapshot还是很稳定的,已经不错了,(不过还有数个小Bug要手工改一下),建议你下载最新的DevSnapshot版本看看.
 
你看下Indy10的demo,不用你自己添加IOHandler,除非你自己需要对IOHandler有什么操作。
把客户端上的TIdIOHandlerStream删掉,你的程序就可以正常运行了。
 
..............Indy不稳定?

晕,还想学下Indy用来做项目。
不会只用Socket吧? 除了直接用原生的Socket,各位做项目网络部分是用什么?
 
unit MainUnitServer;

{

Article:

ScreenThief - stealing screen shots over the Network

http://delphi.about.com/library/weekly/aa012004a.htm

A free network screen shot grabber application,
with source code. Learn how to send / receive raw (binary)
data (screen shot JPG images) using TCP connections.
ScreenThief is a network application designed to &quot;steal&quot;
screen shot images from client computers and display them
in one central location (server application).

..............................................
Zarko Gajic, BSCS
About Guide to Delphi Programming
http://delphi.about.com
how to advertise: http://delphi.about.com/library/bladvertise.htm
free newsletter: http://delphi.about.com/library/blnewsletter.htm
forum: http://forums.about.com/ab-delphi/start/
..............................................
}

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, IdTCPServer, IdSocketHandle, IdBaseComponent,IdContext,
IdComponent, Buttons, ExtCtrls, Jpeg, ImgList, ComCtrls, ToolWin,
IdAntiFreezeBase, IdAntiFreeze, IdStack, SyncObjs, IdCustomTCPServer;
//IdThreadMgr, IdThreadMgrDefault,
type
PClient = ^TClient;
TClient = record
PeerIP : string[15]; { Cleint IP address }
HostName : String[40]; { Hostname }
TakeShot : boolean;
Connected, { Time of connect }
LastAction : TDateTime; { Time of last transaction }
Thread : Pointer; { Pointer to thread }
end;

TMainFormServer = class(TForm)
TCPServer: TIdTCPServer;
pnlMain: TPanel;
ImageScrollBox: TScrollBox;
Image: TImage;
InfoLabel: TStaticText;
pnlLeft: TPanel;
ClientsBox: TGroupBox;
ClientsListBox: TListBox;
DetailsBox: TGroupBox;
DetailsMemo: TMemo;
ActionPanel: TPanel;
AutoCaptureCheckBox: TCheckBox;
SecondsCombo: TComboBox;
GetImageNowButton: TBitBtn;
Protocol: TMemo;
Timer: TTimer;
IdAntiFreeze: TIdAntiFreeze;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ClientsListBoxClick(Sender: TObject);
procedure AutoCaptureCheckBoxClick(Sender: TObject);
procedure GetImageNowButtonClick(Sender: TObject);
procedure TimerTimer(Sender: TObject);
procedure TCPServerConnect(AContext: TIdContext);
procedure TCPServerExecute(AContext: TIdContext);
procedure TCPServerDisconnect(AContext: TIdContext);
procedure FormDeactivate(Sender: TObject);
private
procedure RefreshListDisplay;
procedure RefreshImage(const ClientDNS, ImageName : string);
public
end;

const
// DefaultServerIP = '192.168.0.1';
DefaultServerIP = '127.0.0.1';
DefaultServerPort = 7676;

var
MainFormServer : TMainFormServer;
Clients : TThreadList; // Holds the data of all clients

implementation
{$R *.DFM}

procedure TMainFormServer.FormCreate(Sender: TObject);
var
Bindings: TIdSocketHandles;
begin
//设置并启动TCPServer
Bindings := TIdSocketHandles.Create(TCPServer);
try
with Bindings.Add do
begin
IP := DefaultServerIP;
Port := DefaultServerPort;
end;

try
TCPServer.Bindings:=Bindings;
TCPServer.Active:=True;
except on E:Exception do
ShowMessage(E.Message);
end;
finally
Bindings.Free;
end;
//setup TCPServer

//other startup settings
Clients := TThreadList.Create;
Clients.Duplicates := dupAccept;

SecondsCombo.ItemIndex := 0;
Timer.Enabled := False;
DetailsMemo.Clear;
InfoLabel.Caption := '等待中...';

RefreshListDisplay;

if TCPServer.Active then
begin
Protocol.Lines.Add('远程抓屏服务器运行在' + TCPServer.Bindings[0].IP + ':' + IntToStr(TCPServer.Bindings[0].Port));
end;
end; procedure TMainFormServer.FormDeactivate(Sender: TObject);
begin

end;

(* Form Create *)

procedure TMainFormServer.FormClose(Sender: TObject; var Action: TCloseAction);
var
ClientsCount : integer;
begin
try
ClientsCount := Clients.LockList.Count;
finally
Clients.UnlockList;
end;

if (ClientsCount > 0) then //and (TCPServer.Active) then
begin
Action := caNone;
ShowMessage('有连接的客户端时不能关闭远程抓屏服务器!');
end
else
begin
TCPServer.Active := False;
Clients.Free;
end;
end; (* Form Close *)

procedure TMainFormServer.RefreshListDisplay;
var
AClient :PClient;
i:integer;
begin
GetImageNowButton.Enabled := False;

ClientsListBox.Clear;
DetailsMemo.Clear;

with Clients.LockList do
try
for i := 0 to Count-1 do
begin
AClient := Items;
ClientsListBox.AddItem(AClient.HostName,TObject(AClient));
end;
finally
Clients.UnlockList;
end;

GetImageNowButton.Enabled := ClientsListBox.Items.Count > 0;
AutoCaptureCheckBox.Enabled := GetImageNowButton.Enabled;
end; (* RefreshListDisplay *)


procedure TMainFormServer.ClientsListBoxClick(Sender: TObject);
var
SelClient: PClient;
begin
DetailsMemo.Clear;

if ClientsListBox.ItemIndex <> -1 then
begin
try
SelClient := PClient(Clients.LockList.Items[ClientsListBox.ItemIndex]);
with DetailsMemo do
begin
Lines.Add('IP 地 址: ' + SelClient.PeerIP);
Lines.Add('主 机 名: ' + SelClient.HostName);
Lines.Add('连 接: ' + DateTimeToStr(SelClient.Connected));
Lines.Add('最后取屏: ' + DateTimeToStr(SelClient.LastAction));
Lines.Add('等 待 中: ' + BoolToStr(SelClient.TakeShot, True));
end;
finally
Clients.UnlockList;
end;
end;
end; (* ClientsListBox Click *)

procedure TMainFormServer.AutoCaptureCheckBoxClick(Sender: TObject);
begin
GetImageNowButton.Enabled := NOT AutoCaptureCheckBox.Checked;

Timer.Interval := 1000 * StrToInt(SecondsCombo.Items[SecondsCombo.ItemIndex]);
Timer.Enabled := AutoCaptureCheckBox.Checked;
end; (* AutoCaptureCheckBoxClick *)

procedure TMainFormServer.GetImageNowButtonClick(Sender: TObject);
var
SelClient : PClient;
begin
if ClientsListBox.ItemIndex = -1 then
begin
if Sender is TBitBtn then ShowMessage('请从列表中选择一个客户端!');
Exit;
end;

try
SelClient := PClient(Clients.LockList.Items[ClientsListBox.ItemIndex]);
SelClient.TakeShot := True;
finally
Clients.UnLockList
end;

//refresh DetailsMemo
ClientsListBoxClick(Sender);
end; (* GetImageNowButton Click *)

procedure TMainFormServer.RefreshImage(const ClientDNS, ImageName : string);
begin
Image.Picture.LoadFromFile(ImageName);
InfoLabel.Caption := '取屏来自于: ' + ClientDNS;
end; (* RefreshImage *)

procedure TMainFormServer.TCPServerConnect(AContext: TIdContext); //uses IdContext
var
NewClient: PClient;
begin
GetMem(NewClient, SizeOf(TClient));

NewClient.PeerIP :=AContext.Binding.PeerIP;
NewClient.HostName := GStack.HostByAddress(NewClient.PeerIP);
NewClient.TakeShot := False;
NewClient.Connected := Now;
NewClient.LastAction := NewClient.Connected;
NewClient.Thread := AContext;

AContext.Data := TObject(NewClient);

try
Clients.LockList.Add(NewClient);
finally
Clients.UnlockList;
end;

Protocol.Lines.Add(TimeToStr(Time)+' 连接来自于: &quot;' + NewClient.HostName + '&quot; on ' + NewClient.PeerIP);
RefreshListDisplay;
end;

procedure TMainFormServer.TCPServerDisconnect(AContext: TIdContext);
var
Client: PClient;
begin
Client := PClient(AContext.Data);
Protocol.Lines.Add (TimeToStr(Time)+' 断开连接: &quot;' + Client.HostName+'&quot;');
try
Clients.LockList.Remove(Client);
finally
Clients.UnlockList;
end;
FreeMem(Client);
AContext.Data := nil;

RefreshListDisplay;
end; (* TCPServer Disconnect *)


procedure TMainFormServer.TCPServerExecute(AContext: TIdContext);
var
Client : PClient;
Command : string;
Size : integer;
PicturePathName : string;
ftmpStream : TFileStream;
begin
//if not AThread.Terminated and AThread.Connection.Connected then

if AContext.Connection.Connected then
begin
Client := PClient(AContext.Data);
Client.LastAction := Now;

Command := AContext.Connection.IOHandler.ReadLn;
if Command = 'CheckMe' then
begin
if Client.TakeShot = True then
begin
Client.TakeShot := False;

AContext.Connection.IOHandler.WriteLn('TakeShot');

PicturePathName := ExtractFileDir(ParamStr(0)) + '/' + Client.HostName + '_Screen.JPG';

if FileExists (PicturePathName) then
DeleteFile(PicturePathName);
ftmpStream := TFileStream.Create(PicturePathName,fmCreate);
Size := AContext.Connection.IOHandler.ReadInteger;
AContext.Connection.IOHandler.ReadStream(fTmpStream,Size,False);
FreeAndNil(fTmpStream);

AContext.Connection.IOHandler.WriteLn('DONE');

RefreshImage(Client.HostName, PicturePathName);
ClientsListBoxClick(nil);
end
else
AContext.Connection.IOHandler.WriteLn('DONE');
end;
end;
end;

(* TCPServer Connect *)


procedure TMainFormServer.TimerTimer(Sender: TObject);
begin
Timer.Enabled := False;
GetImageNowButtonClick(Sender);
Timer.Enabled := True;
end; (* TimerTimer *)

end.
 
后退
顶部