局域网内有6台电脑,无服务器.让某台电脑采集到信息时,再通知其他五台电脑.应该如何编程.
信息量不大.
我的思路是用IDTCPSERVER与IDTCPCLIENT ,当某台电脑采集到信息时,发送到另外五台电脑,五台电脑收到后均响应.不知可行否?
同时应如何区分是某台电脑的响应? 请高手指示一下呀/
信息量不大.
我的思路是用IDTCPSERVER与IDTCPCLIENT ,当某台电脑采集到信息时,发送到另外五台电脑,五台电脑收到后均响应.不知可行否?
同时应如何区分是某台电脑的响应? 请高手指示一下呀/
还有最重要一点要把通讯数据加上一个标识,只有其他机器接收到数据中含有这些标识才可以处理的数据,以防止乱数据.然后其他机器同样用这个控件NMUDP1DataReceived方法中写处理就行了.
谢谢yhcslg的回复
据说UDP容易丢包,我想还是用TCP实现,因为我的数据量很小,一般100字节/S最多了.
还有个问题就是如何让不在线的电脑重新在线后也收到(因没有开机或联不上网时的信息呢)? 是不是要做存储或别的什么?
谢谢哦,我是想在其中任一电脑上有信息时才去联接其他联接.而且六台电脑是平等的,用indyudp广播会不会太复杂?
采用tcp也是可以的(timer控件定时统计).
不过你说udp丢包,你6台机器的距离是不是很远.不是很远的或数据不是非常重要的情况下,我们应该选择一个比较简洁的方法.
大致如下;
unit TCPCOMM1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdTCPConnection, IdTCPClient, IdBaseComponent, IdComponent,
IdTCPServer,IniFiles, IdIPWatch, StdCtrls, ExtCtrls ;type
Tcliendthread =class(TThread)
private
{ Private declarations }
procedure createtttimemode;
procedure Deltttimemode;
public
tcpcomm_link:Boolean; //串口错误
readok:Boolean ;//读到数据
readstr:string ;
line_ID:byte;//本线程的ID号
IdTCPClient2: TIdTCPClient;
TCPcommbuf:array[1..256]of byte; //串口接收通讯缓冲区
TCPcommlen:Integer ;
procedure execute; override;
constructor create;
destructor Destroy; override;
protected
end; TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
IdTCPClient1: TIdTCPClient;
IdIPWatch1: TIdIPWatch;
Memo1: TMemo;
Timer1: TTimer;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
tcpserverok,tcpclientok:Boolean;
serverport,clientport:Integer;
ipset,ipname:string ;
ipexitself:Boolean; //=true 自己的IP存在于配置文件中
ipsetall:array [1..10]of string ;
ipnameall:array [1..10]of string ;
cliend1:Tcliendthread; { Public declarations }
end;var
Form1: TForm1;implementation
const porta=50000;
portb=porta+10000;
datafilestr='tcpcomm.ini';
var
currpath:string ;
{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
var i,errNO:Integer;
ini:TIniFile ;
begin
currpath:=ExtractFilePath(Paramstr(0));
CreateMutex(nil,False,pchar(application.title));
errNO:=GetLastError;
If errNO=ERROR_ALREADY_EXISTS Then
begin //检测是否重复运行
// SetDlgAutoClose(5000,True,True);
application.MessageBox('软件重复运行','重复运行',MB_OK);
application.Terminate;
end;
tcpserverok:=False;
serverport:=porta;
IdTCPServer1.DefaultPort:=serverport;
try
IdTCPServer1.Active:=True;
tcpserverok:=true;
except
tcpserverok:=False;
end;
if not tcpserverok then
begin
serverport:=portb;
IdTCPServer1.DefaultPort:=serverport;
try
IdTCPServer1.Active:=True;
tcpserverok:=true;
except
tcpserverok:=False;
end;
end; clientport:=porta;
IdTCPClient1.Port:=clientport; ipset:=IdIPWatch1.LocalIP;
ipname:=IdIPWatch1.LocalName;
Caption:=ipset;
ipexitself:=False;
Ini := TIniFile.Create(currpath+datafilestr);
try
for i:=1 to 10 do
begin
ipsetall[i]:=Ini.ReadString('Ipset','ip'+inttostr(i),'');
ipnameall[i]:=Ini.ReadString('Ipset','ipname'+inttostr(i),'');
if ipsetall[i]=ipset then
begin
ipsetall[i]:='';
ipnameall[i]:='';
ipexitself:=true;
end;
end;
finally
ini.Free;
end; Memo1.Lines.Add(ipname);
Memo1.Lines.Add(ipset);
if ipexitself then Memo1.Lines.Add('自己的IP存在于配置文件中')
else begin
Memo1.Lines.Add('自己的IP没存在于配置文件中');
Beep ; sleep(200) ; Beep ; sleep(200) ; Beep ;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var i,j:Integer;begin
for i:=1 to 10 do
if ipsetall[i]<>'' then
begin
IdTCPClient1.Disconnect;
IdTCPClient1.Host:=ipsetall[i];
IdTCPClient1.Port:=porta;
j:=0;
try
IdTCPClient1.Connect(1000);
j:=1;
if IdTCPClient1.Connected then
begin
Memo1.Lines.Add('连接'+ipsetall[i]+'成功');
IdTCPClient1.WriteLn(ipset+'发给你的信息'); try
// IdTCPClient1.Connect(1000);
cliend1:=Tcliendthread.create; cliend1.IdTCPClient2:=IdTCPClient1;
cliend1.TCPCOMM_LINK:=True;
// cliend1.Resume;
except
cliend1.TCPCOMM_LINK:=False ;
end;
// Memo1.Lines.Add(IdTCPClient1.ReadLn);
j:=0;
while j<10 do
begin
Sleep(100);
j:=j+1;
if cliend1.readok then
begin
memo1.Lines.Add(cliend1.readstr);
cliend1.readok:=False;
cliend1.Suspend;
IdTCPClient1.Disconnect;
j:=10;
end ;
end;
end;
except
end; end;
end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var str1:string;
begin
str1:=AThread.Connection.ReadLn;
Memo1.Lines.add(str1);
str1:=ipset+'收到信息是'+str1;
AThread.Connection.WriteLn(str1);
Memo1.Lines.add('回发的信息是: '+str1);
end;procedure Tcliendthread.execute; //override;
begin
readok :=False;
while True do
begin
if TCPCOMM_LINK then
begin
if IdTCPClient2.Connected then
begin
Sleep(150);
readstr :=IdTCPClient2.Readln;
readok:=True;
end;
end
else
begin
{ try //在线程中连接SERVER无效
IdTCPClient2.Disconnect;
IdTCPClient2.Connect(1000);
TCPCOMM_LINK:=True;
except
TCPCOMM_LINK:=False ;
end;}
end;
end;
end;constructor Tcliendthread.create;
var i:Byte;
ini:TIniFile;
begin
inherited create (False );
// Synchronize(createtttimemode);
TCPcommlen:=0;
//初始化值
end;destructor Tcliendthread.Destroy;
begin
Synchronize(deltttimemode);
inherited Destroy;
end;
procedure Tcliendthread.createtttimemode;
begin
try
// newcomm:=TComPort.Create(nil);
// newcomm.Open;
// newcomm.LoadSettings(stIniFile, currpath+commsetfilestr);
except
ShowMessage('串口配置错误,请重新启动程序或重新配置串口');
end;
end;
procedure Tcliendthread.Deltttimemode;
begin
Sleep(150);
IdTCPClient2:=nil;
// newcomm.Free;
end;
end.
end.