[英]Using UDP Server with Delphi
I have a project made with Delphi 7. I'm getting an error when I compile with Delphi XE7.我有一个用 Delphi 7 制作的项目。当我用 Delphi XE7 编译时出现错误。 The Indy component kit was used in the project.
项目中使用了 Indy 组件套件。 I think the problem is due to differences between Indy 9 and Indy 10. I have tried many methods to solve the problem, but I have not been successful.
我认为问题是由于 Indy 9 和 Indy 10 之间的差异。我尝试了很多方法来解决问题,但都没有成功。 How can I solve this problem?
我怎么解决这个问题?
procedure TRealTimeForm.btnListenClick(Sender: TObject);
begin
try
FUDPServer.DefaultPort := StrToInt(edtPort.Text);
FUDPServer.OnUDPRead:=UDPServerUDPRead;
FUDPServer.Active := True;
btnListen.Enabled := False;
except
on E:Exception do
ShowMessage(e.Message);
end;
end;
procedure TRealTimeForm.UDPServerUDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
var
i: integer;
lReceiveData: array of Byte;
sDIN: string;
year,month,day,hour,minute,second: integer;
rec: IRecordExt;
iInt64: Int64;
begin
{
[0-7]: for check data valid, you can ignore.
[8-23]: these 16 bytes are what you want is the Log entity. The structure is:
Size of structure: 16 bytes
Structure:
//
UINT64 UserID //8 bytes
//
UINT32 Year : 7; //7 bits, MAX: 127, base on 2000.
UINT32 Month : 4; //4 bits
UINT32 Day : 5; //5 bits
UINT32 Action : 4; //4 bits
UINT32 Status : 5; //5 bits
UINT32 JobCode : 7; //7 bits, MAX: 127
UINT32 Antipassback :1; //1 bit
UINT32 DeviceID: 14; //14 bits, MAX: 16383
UINT32 Hour : 5; //5 bits
UINT32 Minute : 6; //6 bits
UINT32 Second : 6; //6 bits
//
//
[24-31]: device physical address.
}
try
if AData.Size < GLogLen then
begin
SetLength(lReceiveData,AData.Size);
AData.ReadBuffer(lReceiveData[0],AData.Size);
ShowDataLog(lReceiveData);
Exit;
end;
SetLength(lReceiveData,GLogLen);
AData.ReadBuffer(lReceiveData[0],GLogLen);
ShowDataLog(lReceiveData);
if not IsCorectGLog(lReceiveData) then
Exit;
rec := CoRecordExt.Create;
iInt64 := 0;
for i := 8 to 15 do
begin
iInt64 := iInt64 + lReceiveData[i] shl ((i-8) * 8);
end;
sDIN := IntToStr(iInt64);
year := lReceiveData[16] and $7F + 2000;
month := ((lReceiveData[16] + lReceiveData[17] shl 8) shr 7) and $0F;
day := (lReceiveData[17] + lReceiveData[18] shl 8) shr 3 and $1F;
hour := (lReceiveData[21] + lReceiveData[22] shl 8) shr 7 and $1F;
minute := (lReceiveData[22] + lReceiveData[23] shl 8) shr 4 and $3F;
second := lReceiveData[23] shr 2 and $3F;
rec.DIN := sDIN;
rec.Clock := EncodeDate(year,month,day) + EncodeTime(hour,minute,second,0);
rec.Verify := (lReceiveData[18] + lReceiveData[19] shl 8) shr 4 and $1F;
rec.Action := lReceiveData[18] and $0F;
rec.DN := (lReceiveData[20] + lReceiveData[21] shl 8 + lReceiveData[22] shl 16) shr 1 and $3FFF;
AddRecord(rec);
FUDPServer.SendBuffer(ABinding.PeerIP,ABinding.PeerPort,lReceiveData[0],GLogLen);
except
on E: Exception do
begin
mmoDataLog.Lines.Add(e.Message);
end;
end;
end;
The parts that give errors:出现错误的部分:
FUDPServer.OnUDPRead:=UDPServerUDPRead;
FUDPServer.SendBuffer(ABinding.PeerIP,ABinding.PeerPort,lReceiveData[0],GLogLen);
In Indy 10, the signature of the OnUDPRead
event and the SendBuffer()
method have both changed.在 Indy 10 中,
OnUDPRead
事件的签名和OnUDPRead
SendBuffer()
方法都发生了变化。 Which you would have easily seen if you looked at the new declarations.如果您查看新声明,您会很容易看到这一点。
Also, in both Indy 9 and 10, you should be sending the response back to the sender using the SendTo()
method of the TIdSocketHandle
object that OnUDPRead
gives you, not the SendBuffer()
method of TIdUDPServer
, which will use the 1st TIdSocketHandle
in the server's Bindings
collection, which may or may not be the correct socket to send with.此外,在 Indy 9 和 10 中,您应该使用
OnUDPRead
为您提供的TIdSocketHandle
对象的SendTo()
方法将响应发送回发件人,而不是TIdUDPServer
SendBuffer()
方法,它将使用第一个TIdSocketHandle
服务器的Bindings
集合,它可能是也可能不是要发送的正确套接字。
Try this instead:试试这个:
procedure TRealTimeForm.btnListenClick(Sender: TObject);
begin
try
FUDPServer.DefaultPort := StrToInt(edtPort.Text);
FUDPServer.OnUDPRead := UDPServerUDPRead;
FUDPServer.Active := True;
btnListen.Enabled := False;
except
on E: Exception do
ShowMessage(e.Message);
end;
end;
procedure TRealTimeForm.UDPServerUDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
i: integer;
sDIN: string;
year, month, day, hour, minute, second: Integer;
rec: IRecordExt;
iInt64: Int64;
begin
{
[0-7]: for check data valid, you can ignore.
[8-23]: these 16 bytes are what you want is the Log entity. The structure is:
Size of structure: 16 bytes
Structure:
//
UINT64 UserID //8 bytes
//
UINT32 Year : 7; //7 bits, MAX: 127, base on 2000.
UINT32 Month : 4; //4 bits
UINT32 Day : 5; //5 bits
UINT32 Action : 4; //4 bits
UINT32 Status : 5; //5 bits
UINT32 JobCode : 7; //7 bits, MAX: 127
UINT32 Antipassback :1; //1 bit
UINT32 DeviceID: 14; //14 bits, MAX: 16383
UINT32 Hour : 5; //5 bits
UINT32 Minute : 6; //6 bits
UINT32 Second : 6; //6 bits
//
//
[24-31]: device physical address.
}
try
if Length(AData) < GLogLen then
begin
ShowDataLog(AData);
Exit;
end;
ShowDataLog(AData);
if not IsCorectGLog(AData) then
Exit;
rec := CoRecordExt.Create;
iInt64 := 0;
for i := 8 to 15 do
begin
iInt64 := iInt64 + AData[i] shl ((i-8) * 8);
end;
sDIN := IntToStr(iInt64);
year := AData[16] and $7F + 2000;
month := ((AData[16] + AData[17] shl 8) shr 7) and $0F;
day := (AData[17] + AData[18] shl 8) shr 3 and $1F;
hour := (AData[21] + AData[22] shl 8) shr 7 and $1F;
minute := (AData[22] + AData[23] shl 8) shr 4 and $3F;
second := AData[23] shr 2 and $3F;
rec.DIN := sDIN;
rec.Clock := EncodeDateTime(year, month, day, hour, minute, second,. 0);
rec.Verify := (AData[18] + AData[19] shl 8) shr 4 and $1F;
rec.Action := AData[18] and $0F;
rec.DN := (AData[20] + AData[21] shl 8 + AData[22] shl 16) shr 1 and $3FFF;
AddRecord(rec);
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, AData, 0, GLogLen);
except
on E: Exception do
begin
mmoDataLog.Lines.Add(e.Message);
end;
end;
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.