繁体   English   中英

如何在UDP中将UDP数据包发送到HLDS服务器?

[英]How to send a UDP packet to the HLDS Server in Delphi?

我想描述的A2A_PING UDP数据包发送到服务器HLDS 这里采用Delphi XE4。 但是,我没有得到任何回应。 当我使用Packet Sender测试时,我在Packet Sender中得到了预期的响应。

我正在尝试做的是创建一个服务器监视器,以在其UDP端口上发送ping命令。 因此,我的应用将始终使用其本地IP在服务器上本地运行。 服务器的UDP端口为27015。

我尝试发送的UDP数据包是:

十六进制:FF FF FF FF 69

等效字符串:ÿÿÿÿi

这是我迄今为止尝试过的:

unit uFrmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, IdUDPServer, IdBaseComponent, IdComponent,
  IdUDPBase, IdUDPClient, IdSocketHandle, IdGlobal;

type
  TfrmMain = class(TForm)
    ListBox1: TListBox;
    btnSendMessage: TButton;
    btnInitialize: TButton;
    procedure btnSendMessageClick(Sender: TObject);
    procedure IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure btnInitializeClick(Sender: TObject);
  private
    function String2Hex(const Buffer: Ansistring): string;
    procedure Initialize;
  public
    { Public declarations }
  end;

const
  Host = '172.30.0.96';
  TargetPort = 27015;
  LocalListenPort = 47001;
  MessageToSend = 'ÿÿÿÿi';  // need to send: FF FF FF FF 69

var
  frmMain: TfrmMain;
  udpServer: TIdUDPServer;
  udpClient: TIdUDPClient;

implementation

{$R *.dfm}

procedure TfrmMain.Initialize;
var
  binding: TIdSocketHandle;
begin
  // Setup UDP Server
  udpServer := TIdUDPServer.Create(frmMain);
  udpServer.Active := false;
  binding := udpServer.Bindings.Add;
  Binding.IP := Host;                 // local host ip
  binding.Port := LocalListenPort;    // Listen for incoming messages on 47001
  udpServer.OnUDPRead := IdUDPServer1UDPRead;
  udpServer.Active := true;

  // Setup UDP client
  udpClient := TIdUDPClient.Create(frmMain);
  udpClient.Host := Host;       // Local host ip
  udpClient.Port := TargetPort; // Send messages to 27015
  udpClient.Active := true;
end;

procedure TfrmMain.btnInitializeClick(Sender: TObject);
begin
  Initialize;
end;

procedure TfrmMain.btnSendMessageClick(Sender: TObject);
begin
    udpClient.SendBuffer(Host, TargetPort, ToBytes(MessageToSend));
end;

procedure TfrmMain.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
    ListBox1.Items.Add(BytesToString(AData));
end;

function TfrmMain.String2Hex(const Buffer: Ansistring): string;
begin
  SetLength(result, 2*Length(Buffer));
  BinToHex(@Buffer[1], PWideChar(@result[1]), Length(Buffer));
end;

end.

根据雷米的建议进行更新 ,我也尝试过这样做:

unit uFrmMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, IdUDPServer, IdBaseComponent, IdComponent,
  IdUDPBase, IdUDPClient, IdSocketHandle, IdGlobal;

type
  TfrmMain = class(TForm)
    ListBox1: TListBox;
    btnSendMessage: TButton;
    btnInitialize: TButton;
    procedure btnSendMessageClick(Sender: TObject);
    procedure IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
    procedure btnInitializeClick(Sender: TObject);
  private
    function String2Hex(const Buffer: Ansistring): string;
    procedure Initialize;
  public
    { Public declarations }
  end;

const
//  Host = '172.30.0.96';
  Host = '192.168.190.1';
  TargetPort = 27015;
  LocalListenPort = 47001;

var
  frmMain: TfrmMain;
  udpServer: TIdUDPServer;
//  udpClient: TIdUDPClient;
  binding: TIdSocketHandle;

implementation

{$R *.dfm}

procedure TfrmMain.Initialize;
var
  bytes_received: integer;
begin
  // Setup UDP Server
  udpServer := TIdUDPServer.Create(frmMain);
  udpServer.Active := false;
  udpServer.DefaultPort := 0;
  binding := udpServer.Bindings.Add;
  Binding.IP := Host;                 // local host ip
  binding.Port := LocalListenPort;    // Listen for incoming messages on 47001
  udpServer.OnUDPRead := IdUDPServer1UDPRead;
  udpServer.Active := true;

  // Setup UDP client
//  udpClient := TIdUDPClient.Create(frmMain);
//  udpClient.Host := Host;       // Local host ip
//  udpClient.Port := TargetPort; // Send messages to 27015
//  udpClient.BoundIP := Host;
//  udpClient.BoundPort := LocalListenPort;
//  udpClient.ReceiveTimeout := 2000;
//  udpClient.Active := true;
end;

procedure TfrmMain.btnInitializeClick(Sender: TObject);
begin
  Initialize;
end;

procedure TfrmMain.btnSendMessageClick(Sender: TObject);
var
  MessageToSend: TIdBytes;
begin
  SetLength(MessageToSend, 5);
  MessageToSend[0] := $FF;
  MessageToSend[1] := $FF;
  MessageToSend[2] := $FF;
  MessageToSend[3] := $FF;
  MessageToSend[4] := $69;
//  udpClient.SendBuffer(Host, TargetPort, RawToBytes(MessageToSend, SizeOf(MessageToSend)));
  binding.SendTo(Host, TargetPort, RawToBytes(MessageToSend, SizeOf(MessageToSend)));
end;

procedure TfrmMain.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
    ListBox1.Items.Add(ToHex(AData));
end;

end.

由于Packet Sender正常工作,我肯定会错过一些非常明显的东西。 任何帮助将不胜感激。

您不应该在消息中使用字符串(如果使用的是Delphi 2009+,则尤其是Unicode字符串)。 您使用的协议本质上是二进制的,不是文本的。 您需要使用原始字节进行操作,例如:

const
  MessageToSend: array[0..4] of Byte = ($FF, $FF, $FF, $FF, $69);

procedure TfrmMain.btnSendMessageClick(Sender: TObject);
begin
  udpClient.SendBuffer(Host, TargetPort, RawToBytes(MessageToSend, SizeOf(MessageToSend));
end;

{
Alternatively:

procedure TfrmMain.btnSendMessageClick(Sender: TObject);
var
  MessageToSend: TIdBytes;
begin
  SetLength(MessageToSend, 5);
  MessageToSend[0] := $FF;
  MessageToSend[1] := $FF;
  MessageToSend[2] := $FF;
  MessageToSend[3] := $FF;
  MessageToSend[4] := $69;
  udpClient.SendBuffer(Host, TargetPort, MessageToSend);
end;
}

procedure TfrmMain.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
begin
  ListBox1.Items.Add(ToHex(AData));
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM