jjzjj

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

coder 2024-06-16 原文

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

我正在使用 Serversocket 和客户端套接字。当我的客户端连接到我的服务器时,我想让它发送一些信息,比如计算机名、LAN IP、操作系统名称、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 方法,而没有首先设计较高级别的协议(protocol)来描述正在发送的数据。你需要一个协议(protocol)。设计您希望数据的外观,然后以这种方式格式化数据并使用方法发送/接收数据,然后在接收到数据时根据需要拆分数据。

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

关于windows - Delphi:通过套接字发送多个字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18559989/

有关windows - Delphi:通过套接字发送多个字符串?的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  6. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  7. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  8. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  9. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  10. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

随机推荐