许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  Delphi中TUDPSocket组件的使用教程

Delphi中TUDPSocket组件的使用教程

阅读数 31
点赞 0
article_banner

       按照Delphi文档上所说,欲在两个socket之间通信,必须一个为client,一个为server。这个概念在TCP上还好说,但是用在UDP上就不大合适了。borland提供的UDP组件只有一个TUDPSocket,按照borland的说法,TUDPSocket即可以作为client也可以作为server使用(UDP下,server与client的区别并不明显,但为了方便我们不妨这么称呼)(参考 turbo delphi win32 developer's guide里的Using Client Sockets和Using Server Sockets)。但是通过源码我们不难发现,TUDPServer是继承于TCustomIPClient的。它被设计为只能当作一个客户端来用。

       通过参考vc++的范例程序得知UDP通信时,server端要做的工作有:open->bind->send/recv->close,其中bind这步很重要,它将一个socket绑定到一个本地地址。document上的原话是:

   This routine is used on an unconnected connectionless or connection-oriented socket, before subsequent connects or listens. When a socket is created with socket, it exists in a name space (address family), but it has no name assigned. bind establishes the local association of the socket by assigning a local name to an unnamed socket.

“这个例程在连接(无连接)与监听(面向连接)之前调用...bind把一个本地的名字绑定到了一个socket上”

       监听是TCPServer的动作,那么相对应的,在UDP中作为Server使用的socket也应当调用bind()。可是在borland提供的socket.pas中bind一共出现了5次,4次在TIPSocket,还有一次出现在TCustomTCPServer。前四次是对socket API的封装,最后一次也是这个.pas中唯一的一次对bind的调用。就是这个bind使TUDPSocket“沦为”了一个客户端。

     TUDPSocket的Open方法会依次建立一个socket,设置好远端地址和端口,然后就自动连接了。没有bind。而唯一的会调用bind的TTCPServer,它在bind后则自动进入了监听状态。对于UDP来说,我们不希望它监听,要达到这个目的,除了写自己的类以外,我们只能从它们的父类入手。

通过观察发现,TIPSocket实现了bind的封装,并且它的open方法继承于TBaseSocket——只完成了socket的创建,这恰恰是我们所需要的。我们只需要手动bind这个socket即可。

源码如下,turbo delphi 2006(ver100)调试通过:


 {server端设置}

program UDPServer;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Sockets,
  WinSock;

const
  DefaultPort='827';
var
  aUDPServer  : TIPSocket;
  addr        : TSockAddr;
  rv,i        : integer;
  quit        : boolean;
  buf         : array [0..255] of byte;
begin
  { TODO -oUser -cConsole Main : Insert code here }
  quit:=false;
  aUDPServer:=TIPSocket.Create(nil);

  aUDPServer.LocalHost:=aUDPServer.LocalHostName;
  aUDPServer.LocalPort:=DefaultPort;
  aUDPServer.Protocol:=IPPROTO_UDP;
  aUDPServer.SockType:=stDgram;
  //aUDPServer.BlockMode:=bmNonBlocking;
  aUDPServer.Active:=true;
  addr:=aUDPServer.GetSocketAddr(aUDPServer.LocalHost,aUDPServer.LocalPort);
  bind(aUDPServer.Handle,addr,sizeof(addr));
  while not quit do
  begin
    fillchar(buf,255,0);
    rv:=aUDPServer.Receivebuf(buf,sizeof(buf));
    if rv<>Socket_Error then
    begin
      for i:=0 to rv do write(inttohex(buf[i],2),' ');
      writeln;
      for i:=0 to rv do write(chr(buf[i]));
      writeln;
    end;
  end;

  if assigned(aUDPServer) then
    aUDPServer.Free;
end.
{client端}
unit UUDPClient;

interface

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

type
  TForm1 = class(TForm)
    UdpSocket1: TUdpSocket;
    Button1: TButton;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
const
  DefaultPort = '827';
procedure TForm1.FormCreate(Sender: TObject);
begin
  with UdpSocket1 do
  begin
    RemoteHost:='121.195.43.77';
    RemotePort:=DefaultPort;
    Active:=true;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  buf : array [1..256] of byte;
  i:integer;
begin
  fillchar(buf,length(buf),0);
  if length(edit1.Text)<length(buf) then
  begin
    for i:=1 to length(edit1.Text) do buf[i]:=byte(edit1.Text[i]);
    UDPSocket1.SendBuf(buf,length(edit1.Text));
  end;
end;

end.


 相关资源:TTcpClient&TTcpServer示例代码._RFID示例代码资源
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空