一台PC 对多个IP端的监控基本结构:
一台PC---> 局域网---> IP端(有300个,全是硬件:如PLC)PC :可以作为服务器端也可以为客户端
多个IP端:可作为TCPClient端、TCPServer端、UDPServer\Client端等、要求:由PC 端主动向多个IP端发送数据,由于是按一种协议的格式来发送的,多个IP端会自动有数据返回,我现在不知道究竟把PC 端作SERVER端好还是CLIENT端好?用UDP 方式好还是用TCP方式好??请大家给些可行的建议。
一台PC---> 局域网---> IP端(有300个,全是硬件:如PLC)PC :可以作为服务器端也可以为客户端
多个IP端:可作为TCPClient端、TCPServer端、UDPServer\Client端等、要求:由PC 端主动向多个IP端发送数据,由于是按一种协议的格式来发送的,多个IP端会自动有数据返回,我现在不知道究竟把PC 端作SERVER端好还是CLIENT端好?用UDP 方式好还是用TCP方式好??请大家给些可行的建议。
解决方案 »
- 通用数据库及文件同步软件《同步专家网络版》
- 奥运会开始了,散点分
- 怎样在delphi里执行bat命令
- 【明年差不多这个时候,我儿子就要出生了,大家帮忙想个名....】
- 怎样得到api:MessageBox()中按钮的大小和间距,以及和对话框的边缘距离?另外内详。。。
- 强烈要求FrameSniper版主马上辞去版主职位!!!!!!!
- 大家帮忙看一下关于TreeView的相关问题!
- 如何得到sql表在插入时自动加一的id值?
- 在状态栏中,怎么动态显示当前时间?
- 用findfirst 和 findnext怎么样区分文件和目录?
- 请大家帮忙,有关 DImageEn 控件,用过的朋友请进~~~~~~~~~
- wise 9.0 安装
一台PC---> 局域网---> IP端(有300个,全是硬件:如PLC)上面这个结构可以看成是: 一台主控PC---> 局域网---> 多个被控PC不用管 被控端是什么硬件,因我在连接硬件时用了一个“串口转TCP/IP转换器”“串口转TCP/IP转换器”:有一个IP 地址,我只要从PC端向“串口转TCP/IP转换器”发送数据就可以啦,它会自动把IP数据包送到硬件上的.
unit UnitGetOnLineList;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp;const
ClientMax=254; //客户端最大连接数
type
Client_Record=Record
ClientHandle: Integer; //客户端套接字句柄
ClientSocket:TCustomWinSocket; //客户端套接字
ClientName:String; //客户端计算机名称
ClientAddress:String; //客户端计算机IP地址
ClientUsed: Boolean; //客户端联机标志
end;type
TFrmGetOnLineList = class(TForm)
ServerSocket1: TServerSocket;
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
Session: array[0..ClientMax] of Client_record; //客户端连接数组
Sessions: integer;
procedure GetOnLineList(var ASocketIndex:integer); //获取在线用户列表;
public
{ Public declarations }
end;var
FrmGetOnLineList: TFrmGetOnLineList;implementationuses UnitDM, UnitLogin;{$R *.dfm}
procedure TFrmGetOnLineList.GetOnLineList(var ASocketIndex:integer);
var
i:integer;
SL:TStringList;
temp:string;
begin
with DM1.ADOQuery1 do
begin
SL:=TStringList.Create;
try
for i := 0 to FrmLogin.lbxClientNumber.Items.Count-1 do
begin
temp:='';
SQL.Clear;
SQL.Add('Select 号码,昵称,性别,省份,头像 From RegUser ');
SQL.Add('Where 号码='+FrmLogin.lbxClientNumber.Items.Strings[i]); Open;
if RecordCount<>0 then
begin
temp:=Trim(FieldValues['号码'])+','+
Trim(FieldValues['昵称'])+','+
Trim(FieldValues['性别'])+','+
Trim(FieldValues['省份'])+','+
Trim(FieldValues['头像'])+','+
Trim(FrmLogin.lbxClientIP.Items.Strings[i]);
SL.Append(temp);
end;
Close;
end;
if SL.Text='' then
Session[ASocketIndex].ClientSocket.SendText('3002')
else
Session[ASocketIndex].ClientSocket.SendText(SL.Text);
finally
SL.Free;
end;
end;
end;procedure TFrmGetOnLineList.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i,k:integer;
begin
k:=-1;
for i:=0 to Sessions do
begin
//在原有的客户端连接数组中有中断的客户端连接
if not Session[i].ClientUsed then
begin
Session[i].ClientHandle := Socket.SocketHandle ; //客户端套接字句柄
Session[i].ClientSocket := Socket; //客户端套接字
Session[i].ClientName := Socket.RemoteHost ; //客户端计算机名称
Session[i].ClientAddress := Socket.RemoteAddress ; //客户端计算机IP
Session[i].ClientUsed := True; //连接数组当前位置已经占用
Break;
end;
k:=i;
end;
if k=Sessions then
begin
inc(Sessions);
Session[k].ClientHandle := Socket.SocketHandle ;
Session[k].ClientSocket := Socket;
Session[k].ClientName := Socket.RemoteHost ;
Session[k].ClientAddress := Socket.RemoteAddress ;
Session[k].ClientUsed := True;
end;end;procedure TFrmGetOnLineList.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
i:integer;
begin
for i:=0 to Sessions do
begin
if Session[i].ClientHandle =Socket.SocketHandle then
begin
Session[i].ClientHandle :=0;
Session[i].ClientUsed := False;
Break;
end;
end;end;procedure TFrmGetOnLineList.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
end;procedure TFrmGetOnLineList.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ReceiveString:Widestring;
SocketIndex:integer;
begin
//将从客户端读取的信息添加到Memo1中
ReceiveString:=Socket.ReceiveText;
for SocketIndex:=0 to Sessions do
begin
//取得匹配的客户端
if Session[SocketIndex].ClientHandle = Socket.SocketHandle then
GetOnLineList(SocketIndex);
end;
end;end.这样 这个服务端可同时处理254个客户请求。
主控PC端 为TCPServer?
被控多个IP端 为TCPClient端?我要求:由“主控PC端”主动向“被控多个IP端”发送数据,而且需要对“被控多个IP端”进行时实的数据发送.
一台PC---> 局域网---> IP端(有300个,全是硬件:如PLC)这台PC做成客户端比较合适。主要的原因是PLC这类设备一般不会主动往外送数据,而是收到指令才输出数据,在PC端与硬件设备连接成功之后,发送指令给设备。当然,PC做成服务器端也是可行的,此时,当PC端发现硬件设备与之连接之后,再发送指令给设备。PC端的程序肯定需要维护一个硬件设备的列表, 在列表中填入所有硬件设备的IP地址。程序运行之后,可以用300多个ClientSocket去同时连接这些硬件设备(一台PC可以同时创建上万个Socket,你只有300多个,没问题)。(在你的这种应用中,这台PC可以称之为"数据采集网关"。)通讯协议应该使用TCP,因为你的数据交换是要求必须可靠无误的,只有TCP才能提供可靠的数据连接。而且也只有TCP协议才能比较容易地发现连接被断开等连接故障。
回复人: jadeluo(秀峰) 当然,PC做成服务器端也是可行的,此时,当PC端发现硬件设备与之连接之后,再发送指令给设备。
TO 回复人: jadeluo(秀峰) 不能。服务器端只负责侦听,并接收客户端的连接请求。===========================================
如果是这样的话,我觉得用UDP 好像更合适耶~UDP 是不区分服务器端和客户端的,它只是分为发送端和接收端,发送数据时,连IP和PORT都在写在里面,那么我在PC 上写程序时应该用一个UPD控件就可以做到了,
--------------------------------------
记得好像你用过MOXA公司的产品(串口转TCP/IP 卡)方面的,我用的是MOXA公司的产品(NPort DE-311)串口转TCP/IP 卡,好像可以由它(如:把它设为TCPClient)主动向PC端(TCPServer)发起连接; 这样的话,我就好做了,我直接在PC端(TCPServer)向多个TCPClient端发送数据就可以啦还有,我打算用INDY:IdTCPServer控件,我看一下他的使用说明,IdTCPServer控件好像没有发送的命令,而IdTCPClient控件有发送命令:WriteBuffer;如果IdTCPServer控件有发送命令的啦,我又怎么来指写它向哪个IP发送数据呀?
IdTCPServer控件的ReadBuffer接收命令好像也不能得到是哪个IP客户端来的数据,我需要知道是哪个客户端IP,以便做其它操作。
1. PC端做成服务器端,只要建立一个ServerSocket实例,转换器请求连接时,由ServerSocket实例自动创建一个Socket与之相连,而这个客户端是哪一个,则需要通过查找PC端预配置好的IP地址清单才能知道。2. PC端做成客户端,需要按照PC端预配置好的IP地址清单,建立若干个Socket与转换器连接。个人认为,应该是PC端做成客户端更容易一些。另外,建议使用TClientSocket或者TServerSocket,而不要使用IdTCPClient或者IdTCPServer。
------------------------------------------------ 谢谢你的答复,按照你说的,在PC端作为TClientSocket,我将生成300个TClientSocket实例或用300个控件,分别对300个不同IP端(TServerSocket)进行数据发送,那么我觉得应该用一个线程,专门用来发送, 由于我每次发送都有数据自动返回,固还要建立一个线程用来接收数据,这样应该比较好吧?