我的程序的功能是这样的:
我接接收用户发送过来的信息,并将这个信息转发给一个系统(A)。当系统A有返回信息的时候,又将这个信息转发给用户。我的程序中使用了一个TIdTCPServer和一个TIdTCPClient控件。
使用TIdTCPServer控件来接收用户发送过来的信息,使用TIdTCPClient控件是用来接收一个系统(A)发送过来的数据。我在TIdTCPServer的OnExecute事件中得到用户的信息。并保存AThread.Connection。然后在一个线程中使用TIdTCPClient(已经和系统A连接好)接收系统的信息,并使用AThread.Connection发送给用户。各位大虾,我的这种方法对吗???
然后在一个线程中使用TIdTCPClient(已经和系统A连接好)接收系统的信息,并使用AThread.Connection发送给用户---同意使用tidtcpclient,但使用AThread.Connection是什么意思建议看看indy的demo
Demo上的例子只是发送一个,再接收一个,就完了的!!!
我在TIdTCPServer的OnExecute事件中得到用户的信息。并保存AThread.Connection----这个应该可行好象不行的,因为AThread.Connection它会清空的。(不知道什么时候清空的)。
procedure TClientHandleThread.Execute;
var
Size:Integer;
Temp:String;
begin
while true do
begin
if Proxy_Frm.IdTCPClient1.Connected then
try Temp:=Proxy_Frm.IdTCPClient1.CurrentReadBuffer;
Size:=Length(Temp);
if Temp<>'' then
begin
Socket1.Send(Temp,length(Temp));
end;
except
end;
end;
end;当我第一次将数据接收后,进行第2次接收的时候,却出现错无了!!为什么呢???
可以把AThread.Connection的保存起来啊比如一个全局变量什么的,你也说“并保存AThread.Connection”的啊,或者就在OnExecute事件中处理"我看了Demo可是发现没有这样让TIdTCPClient一直等待接收系统信息的"---既然是等待数据的那为什么不用server呢,用server接收数据然后用client发送数据(不知道行不行),或者用client的onwork事件
同时等待哪个系统的返回,在转发给用户的。
unit Proxy_Server;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, te_controls, ExtCtrls, ComCtrls, te_engine, IdBaseComponent,
IdComponent, IdTCPServer, IdMappedPortTCP,IniFiles, IdTCPConnection,
IdTCPClient, Menus, Winsock,Public_Unit,
IdIOHandler, IdIOHandlerSocket;type
TProxy_Frm = class(TForm)
TeThemeEngine1: TTeThemeEngine;
TeThemeList1: TTeThemeList;
TeForm1: TTeForm;
TeSPageControl1: TTeSPageControl;
TeListView1: TTeListView;
TePanel1: TTePanel;
TeButton1: TTeButton;
TePanel2: TTePanel;
TeListView2: TTeListView;
TeButton2: TTeButton;
Timer1: TTimer;
IdTCPClient1: TIdTCPClient;
IdTCPServer1: TIdTCPServer;
procedure Timer1Timer(Sender: TObject);
procedure CustomItem1Click(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
procedure ReadConfig();
procedure ProxyToSybase(SendStr:String);
end; TClientHandleThread = class(TThread)
private
protected
procedure Execute; override;
end;var
Proxy_Frm: TProxy_Frm;
ProxyIP:String;
ProxyPort:Integer;
LocalPort:Integer;
Num:Integer;
wsData:TWSADATA;
sck:TSOCKET;
sto:SOCKADDR_IN;
flag:Boolean;
RevJudge:Boolean;
ClientHandleThread: TClientHandleThread; // variable (type see above)const
ConfignName ='Config.ini';
implementation//定义发送USB端口的信息
function SendUsbInfo():Integer;stdcall;
var
I:Integer;
begin
while true do
begin
//等待发送
if CurrentRelax<>0 then
begin
for I:=Low(SendRelax) to high(SendRelax) do
begin
if (SendRelax[I].Flag) then
begin
//开始通过USB进行发送
Proxy_Frm.ProxyToSybase(SendRelax[I].SendStr);
//发送完毕后的处理
SendRelax[I].SendStr:='';
SendRelax[I].SendLen:=0;
SendRelax[I].Flag:=false;
Dec(CurrentRelax);
if CurrentRelax=0 then
begin
break;
end;
end;
end;
end
else
begin
Sleep(20);
end;
end;
end;procedure TClientHandleThread.Execute;
var
Size:Integer;
Temp:String;
begin
while true do
begin
if Proxy_Frm.IdTCPClient1.Connected then
try
Proxy_Frm.IdTCPClient1.ReadFromStack();
Size:=Proxy_Frm.IdTCPClient1.InputBuffer.Size;
Temp:=Proxy_Frm.IdTCPClient1.ReadString(Size);
CurrConnect.Write(Temp);
except
end;
end;
end;{$R *.dfm}
procedure TProxy_Frm.ProxyToSybase(SendStr:String);
var
Size:Integer;
Temp:String;
begin
if IdTCPClient1.Connected then
begin
IdTCPClient1.Write(SendStr);
end;
end; procedure TProxy_Frm.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled:=false;
ReadConfig();
Proxy_Frm.Hide;
end;procedure TProxy_Frm.CustomItem1Click(Sender: TObject);
begin
show();
end;procedure TProxy_Frm.IdTCPServer1Execute(AThread: TIdPeerThread);
var
Test:String;
Size:Integer;
begin
if AThread.Connection.Connected then
begin
AThread.Connection.ReadFromStack;
Size:=AThread.Connection.InputBuffer.Size;
Test:=AThread.Connection.ReadString(Size);
if Size<>0 then
begin
CurrConnect:=AThread.Connection;
//填充缓存
SendRelax[CurrentRelax].SendLen:= Size;
SendRelax[CurrentRelax].SendStr:=Test;
SendRelax[CurrentRelax].Flag:=true;
//当前缓存加一
Inc(CurrentRelax);
Test:='';
end;
end;
end;procedure TProxy_Frm.FormCreate(Sender: TObject);
var
I:Integer;
hThread,hThread1:THANDLE;
ThreadID,ThreadID1:DWORD;
begin
Num:=0;
//定义发送缓存信息
SetLength(SendRelax,SendMaxPacket);
for I:=Low(SendRelax) to high(SendRelax) do
begin
SendRelax[I].SendLen:=0;
SendRelax[I].Flag:=false;
end;
CurrentRelax:=0;
//定义接收缓存信息
SetLength(RevRelax,SendMaxPacket);
for I:=Low(RevRelax) to high(RevRelax) do
begin
RevRelax[I].SendLen:=0;
RevRelax[I].Flag:=false;
end;
CurrentRev:=0;
CurrConnect:=NIL;
Socket1:=NIl;
//定义发送线程
hThread:=CreateThread(Nil,0,@SendUsbInfo,Nil,0,ThreadID);
ClientHandleThread := TClientHandleThread.Create(True);
ClientHandleThread.FreeOnTerminate:=True;
ClientHandleThread.Resume;
IdTCPClient1.Connect(10000);
end;
procedure TProxy_Frm.ReadConfig();
var
ini:TIniFile;
FilePath:String;
begin
FilePath:= ExtractFilePath(Application.ExeName)+ConfignName;
ini:=Tinifile.Create(FilePath);
//得到代理服务器的IP地址
ProxyIP:=Trim(ini.ReadString('Config','ProxyIP','200.200.200.222'));
//得到代理服务器的端口
ProxyPort :=ini.ReadInteger('Config','ProxyPort',5000);
//得到本地代理服务器的端口
LocalPort:=ini.ReadInteger('Config','LocalPort',888);
ini.Free;
end;
procedure TProxy_Frm.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
AThread.Terminate;
end;end.unit Public_Unit;interface
uses
IdTCPConnection,IdTCPServer,Winsock,IdIOHandlerSocket;const
PacketMax = 512+5; {定义数据包的大小}
SendMaxPacket = 1024; {定义缓存大小}type
tagSendList = record
SendLen:longint; //缓冲数据的长度
SendStr:String; //需要发送的内容
Flag: Boolean; //此缓存是否为空标记
end;
TSendList = tagSendList;
PSendList = ^tagSendList;
var
SendRelax:array of TSendList; {定义发送缓存}
CurrentRelax:Integer; {定义当前发送缓存数} RevRelax:Array of TSendList; {定义接收缓存}
CurrentRev:Integer; {定义当前接收缓存数} AllThread:TIdPeerThread;
CurrConnect:TIdTCPServerConnection;
Socket1:TIdIOHandlerSocket;
implementationend.大家帮助看看吧!!!
只说:Indy在实际应用中是需要修改其内部VCL组件才能适应你的需求的最经常需要修改的地方就是ReadFromSTack方法和数据读取部分的代码http://lysoft.7u7.net
或者看看它的源码实现
这完全实现了你要的东西。
能详细的饿说一下吗??
halfdream(哈欠)
其实单是一个转发的话我已经可以使用TIdMappedPortTCP来实现了。但是现在是我接收到数据以后需要进行各种处理。所以使用TIdMappedPortTCP是不可以的。你说的TIdTunnelMaster我到是没有用过!!
var
Size:Integer;
Temp:String;
begin
while true do
begin
if Proxy_Frm.IdTCPClient1.Connected then
try Temp:=Proxy_Frm.IdTCPClient1.CurrentReadBuffer;
Size:=Length(Temp);
if Temp<>'' then
begin
// Socket1.Send(Temp,length(Temp));//这句错了。
Socket1.Send(pchar(Temp)^,length(Temp));//这样改
end;
except
end;
end;
end;
能看看我上面的代码吗??
我发现我在接收的时候,第一次的Proxy_Frm.IdTCPClient1.Connected 是true但是,以后就是FALSE了!!
能留个MSN吗??