• 在Delphi中关于UDP协议的实现


    首先我把UDP无连接协议的套接字调用时序图表示出来

    在我把在Delphi中使用UDP协议实现数据通讯收发的实现方法总结如下:

      例子描述:下面例子是我的一个实际设备通讯的例子,使用UDP协议在4660端口上发送'F1,00'(16进制,2个字节),在同一个端口上接收到'F1,00,00,00,00,00'((16进制,2个字节))


    1.使用底层函数来实现

    procedure TForm1.FormCreate(Sender: TObject);
    var
        WSAData:TWSAData;
    begin
        edtHost.Text:=192.168.1.222';
        edtPort.Text:='4660';
    //1.初始化Winsock
        if (WSAStartup(MAKEWORD(2,0),WSAData)<>0) then
        begin
            //初始化失败
            memInfo.Lines.Add('Winsock Init Failed');
            exit;
        end
        else
            memInfo.Lines.Add('Socket Start');
    end;
    procedure TForm1.btnFingerClick(Sender: TObject);
    var
        Info:string;
        BufSend,BufRecv:array[0..1024] of byte;
        skt:TSOCKET;
        addr:TSockAddr;
        Re:Integer;
        S:String;
        i:Integer;
    begin

    //=====================数据发送=========================================
       //2.建立socket
        skt:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if(skt=INVALID_SOCKET)then
        begin
            memInfo.Lines.Add('Error:Create socket failed!');
            exit;
        end;
       //3.连接主机
        ZeroMemory(@addr,sizeof(addr));
        addr.sin_family :=AF_INET;
        addr.sin_addr.s_addr :=inet_addr('192.168.1.222');
        addr.sin_port:=htons(4660);
        Re := connect(skt,addr,sizeof(addr));
        if(Re<>0)then
        begin
             memInfo.Lines.Add('Connect to server failed');
             exit;
        end;
      //4.发送信息
        BufSend[0]:=$F1;
        BufSend[1]:=0;
        Re:=send(skt,BufSend,2,0);
        if(Re=SOCKET_ERROR)then
        begin
             memInfo.Lines.Add('Send Data Failed');
             exit;
        end;
      //6.关闭socket
        closesocket(skt);

    //=============接收数据的==================================

       //2.建立socket
        skt:=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if(skt=INVALID_SOCKET)then
        begin
            memInfo.Lines.Add('Error:Create socket failed!');
            exit;
        end;
       //3.绑定主机
        ZeroMemory(@addr,sizeof(addr));
        addr.sin_family :=AF_INET;
        addr.sin_addr.s_addr :=inet_addr('192.168.1.106');
        addr.sin_port:=htons(4660);
        Re := Bind(skt,addr,sizeof(addr));
        if(Re<>0)then
        begin
             memInfo.Lines.Add('Connect to server failed');
             exit;
        end;
       //4.接收信息
        Re:=Recv(skt,BufRecv,6,0);
        if(Re=SOCKET_ERROR)then
        begin
             memInfo.Lines.Add('Send Data Failed');
             exit;
        end
        else
        begin
          S:='';
          for i:=0 to Re-1 do
          begin
            S:=S+IntToHex(Integer(BufRecv[i]),2);
          end;
          memInfo.Lines.Add(S);
        end;
      //6.关闭socket
        closesocket(skt);
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    //6.释放Winsock
    WSACleanUP();
    end;

    2.使用TUDPSocket组件实现

    TUDPSocket组件是继承于TCustomIPClient的。它被设计为只能当作一个客户端来用

    所以它是不能直接用来接收数据的,要是实现接收必须另外定义一个接收的TIPSocket,重新绑定接口.

     type
      TForm2 = class(TForm)
        UdpSocket1: TUdpSocket;
        Button1: TButton;
        UdpSocket2: TUdpSocket;
        procedure FormCreate(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        aUDPServer:TIPSocket;
      end;

    var
      Form2: TForm2;

    implementation

    {$R *.dfm}

    procedure TForm2.FormCreate(Sender: TObject);
    var
       addr:sockAddr_In;
    begin
      UdpSocket1.RemoteHost:='192.168.1.222';
      UdpSocket1.RemotePort:='4660';
      UdpSocket1.Open ;

      aUDPServer:=TIPSocket.Create(nil);
      aUDPServer.RemoteHost:='192.168.1.222';
      aUDPServer.RemotePort:='4660';
      aUDPServer.LocalHost:=aUDPServer.LocalHostName;
      aUDPServer.LocalPort:='4660';
      aUDPServer.Protocol:=IPPROTO_UDP;
      aUDPServer.SockType:=stDgram;
      aUDPServer.Active:=true;
      addr:=aUDPServer.GetSocketAddr(aUDPServer.LocalHost,aUDPServer.LocalPort);
      bind(aUDPServer.Handle,addr,sizeof(addr));

    end;

    procedure TForm2.Button1Click(Sender: TObject);
    var
      ReceivedString:string;
      Buff:array[0..1] of byte;
      RevBuf:array[0..1024] of byte;
      RevSize:Integer;
      i:Integer;
      S:string;
      ToAddr:sockAddr_In;
      Len:integer;
      a:in_Addr;
    begin
        Buff[0]:=$F1;
        Buff[1]:=0;
        UdpSocket1.SendBuf(Buff,2);
        ToAddr:=UdpSocket2.GetSocketAddr(UdpSocket2.LocalHost,UdpSocket2.LocalPort);
         bind(UdpSocket2.Handle,ToAddr,sizeof(ToAddr));
        RevSize:=UdpSocket2.ReceiveBuf(RevBuf,6) ;
        S:='';
        for i:=0 to RevSize-1 do
        begin
          S:=S+IntToHex(Integer(RevBuf[i]),2);
        end;
          ShowMessage(S);
    end;
    3.使用TIdUDPClient组件实现

    TIdUDPClient组件中重新绑定了一个Socket,用来专门接收数据,所以本身一个组件就可以实现接收

    procedure TForm1.Button1Click(Sender: TObject);
    var
      ReceivedString:string;
      Buff:array[0..1] of byte;
      RevBuf:array[0..1024] of byte;
      RevSize:Integer;
      i:Integer;
      S:string;
    begin
        Buff[0]:=$F1;
        Buff[1]:=0;
        IdUDPClient1.SendBuffer(Buff,2);
        RevSize:=IdUDPClient1.Binding.Recv(RevBuf,6,0);
        S:='';
        for i:=0 to RevSize-1 do
        begin
          S:=S+IntToHex(Integer(RevBuf[i]),2);
        end;
          ShowMessage(S);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        IdUDPClient1.Host:='192.168.1.222';
        IdUDPClient1.Binding.Port:=4660;
        IdUDPClient1.Binding.Bind;
        IdUDPClient1.Active:=True;

    end;
    3.使用TNMUDP组件实现

    这里我发现在第一次运行时,要连续按两次按钮,才能收到数据

    procedure TForm1.BitBtn2Click(Sender: TObject);
    var
      Buf:array[0..1] of char;
      RevBuf :array[0..1024] of char;
      ss:string;
      i:integer;
      Len:Integer;
    begin

     Buf[0]:=char($F1);
     Buf[1]:=char(0);
     NMUDP1.SendBuffer(Buf[0],2);
     NMUDP1.ReadBuffer(RevBuf[0],Len);
     if Len>0 then
     begin
         ss:='';
        for i:=1 to Len do
        begin
         ss:=ss + intToHex(integer(RevBuf[i]),2);
        end;
        ShowMessage(ss);
     end;

    end;

    http://blog.sina.com.cn/s/blog_562349090101dizl.html

  • 相关阅读:
    各种地
    傅里叶变换
    点对点通信模型
    take office|boast|think twice|dispose of|level|stuff|'s mature for|a green hand|'s a slave to|
    resume|issue|transmit|sake|obliged|beyond her wildest dreams|echo|transmission|immense|consistent |convey to| boasted|satisfaction|rub|enrol|demonize
    but for|lest,in case和for fear (that)|confidential|item|adapted for|fee|debates| retain|substantial|proceeded to|refrain from|clear|perceive
    pressure to compete|listen to sb do|have sb do|felt like|shouldn't have done|spring up|in honour of|not more than|much as|
    the Uneducated are|anymore|that| so as to |die from|die of|
    the extent of|fill in|find itimpossible to|something|the other day|Be man enough to do sth/for sth|cure sb of |draw out| gone over|made for | see someone off,|
    when|nobody|hazard|lane|circuit|
  • 原文地址:https://www.cnblogs.com/findumars/p/6436014.html
Copyright © 2020-2023  润新知