Windows Delphi:通过套接字发送多个字符串?

Windows Delphi:通过套接字发送多个字符串?,windows,delphi,sockets,Windows,Delphi,Sockets,我目前正在使用Delphi6(是的,我知道……但到目前为止,它已经完成了工作。) 我正在使用服务器套接字和客户端套接字。当我让我的客户端连接到我的服务器时,我想让它发送一些信息,比如computername、lanip、OS name、ping 目前我只有客户端将计算机名发送到服务器,我想知道如何发送多个信息,并在我的网格中进行相应设置?以下是源代码: 客户: unit client1; interface uses Windows, Messages, SysUtils, Varian

我目前正在使用Delphi6(是的,我知道……但到目前为止,它已经完成了工作。)

我正在使用服务器套接字和客户端套接字。当我让我的客户端连接到我的服务器时,我想让它发送一些信息,比如computername、lanip、OS name、ping

目前我只有客户端将计算机名发送到服务器,我想知道如何发送多个信息,并在我的网格中进行相应设置?以下是源代码:

客户:

unit client1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp;

type
  TForm1 = class(TForm)
    Client1: TClientSocket;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Client1Connect(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function Getusernamefromwindows: string;
var
iLen: Cardinal;
begin
 iLen := 256;
 Result := StringOfChar(#0, iLen);
 GetUserName(PChar(Result), iLen);
 SetLength(Result, iLen);
end;


function Getcomputernamefromwindows: string;
var
iLen: Cardinal;
begin
 iLen := MAX_COMPUTERNAME_LENGTH + 1;
 Result := StringOfChar(#0, iLen);
 GetComputerName(PChar(Result), iLen);
 SetLength(Result, iLen);
end;

function osver: string;
begin
result := 'Unknown';
case Win32MajorVersion of
4:
  case Win32MinorVersion of
  0: result := 'windows 95';
  10: result := 'Windows 98';
  90: result := 'Windows ME';
  end;
5:
  case Win32MinorVersion of
  0: result := 'windows 2000';
  1: result := 'Windows XP';
  end;
6:
  case Win32MinorVersion of
  0: result := 'Windows Vista';
  1: result := 'Windows 7';
  end;
end;
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
   Client1.Host := '192.168.1.106';
   Client1.Active := true;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Client1.Active := false;
end;

procedure TForm1.Client1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Client1.Socket.SendText(Getcomputernamefromwindows + '/' + Getusernamefromwindows);
   (*Upon connection to server, I would like it send the os name, but as you
     can see I already have SendText being used*)

end;

end.
服务器:

    unit server1;

interface


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ScktComp, Grids, DBGrids;

type
  TForm1 = class(TForm)
    Server1: TServerSocket;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure Server1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);


  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}






procedure TForm1.FormCreate(Sender: TObject);
begin
 With StringGrid1 do begin

 Cells[0,0] := 'Username';
 Cells[1,0] := 'IP Address';
 Cells[2,0] := 'Operating System';
 Cells[3,0] := 'Ping';

 end;
end;

(* cells [0,0][1,0][2,0][3,0]
   are not to be changed for
   these are used to put the
   titles in
*)





procedure TForm1.Server1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var

begin

     with StringGrid1 do begin

   Cells[0,1] := Socket.ReceiveText;
   Cells[1,1] := Server1.Socket.Connections[0].RemoteAddress;
   (*in this area I want it to receive the os version info and place it in
     Cells[2,1]*)
   end;
end;

end.

你已经知道答案了,因为你已经在做了。发送中间带有分隔符的各种字符串(在您的示例中,您使用的是
/
,但也可以使用CRLF、字符串长度前缀等),然后发送一些最终的分隔符来表示数据的结束

代码的真正问题是使用了
SendText()
ReceiveText()
SendText()
不能保证一次性发送整个字符串。它返回实际发送的字节数。如果小于字符串长度,则必须再次调用
SendText()
以发送剩余字节。至于
ReceiveText()
,它只返回套接字上当时的任意数据,这些数据可能是不完整的字符串,也可能是合并在一起的多个字符串

您正在使用较低级别的I/O方法,而没有首先设计更高级别的协议来描述所发送的数据。你需要一个协议。设计您希望数据的外观,然后以这种方式格式化数据,并使用发送/接收数据的方法,然后在收到数据时根据需要分离数据


因此,在本例中,您可以发送一个包含
/
分隔值的单个CRLF分隔字符串。然后,服务器将一直读取,直到到达CRLF,然后拆分行并使用相应的值。

您已经知道答案,因为您已经在这样做了。发送中间带有分隔符的各种字符串(在您的示例中,您使用的是
/
,但也可以使用CRLF、字符串长度前缀等),然后发送一些最终的分隔符来表示数据的结束

代码的真正问题是使用了
SendText()
ReceiveText()
SendText()
不能保证一次性发送整个字符串。它返回实际发送的字节数。如果小于字符串长度,则必须再次调用
SendText()
以发送剩余字节。至于
ReceiveText()
,它只返回套接字上当时的任意数据,这些数据可能是不完整的字符串,也可能是合并在一起的多个字符串

您正在使用较低级别的I/O方法,而没有首先设计更高级别的协议来描述所发送的数据。你需要一个协议。设计您希望数据的外观,然后以这种方式格式化数据,并使用发送/接收数据的方法,然后在收到数据时根据需要分离数据

因此,在本例中,您可以发送一个包含
/
分隔值的单个CRLF分隔字符串。然后,服务器将读取数据,直到到达CRLF,然后拆分行并根据需要使用值