www.pudn.com > modbus_udp.rar > UDPClientMain.~pas, change:2012-07-20,size:19050b


{----------------------------------------------------------------------------- 
 Demo Name: UDP Client 
 Author:    <unknown - please contact me to take credit! - Allen O'Neill> 
 Copyright: Indy Pit Crew 
 Purpose: 
 History: 
 Date:      27/10/2002 01:00:36 
 Checked with Indy version: 9.0 - Allen O'Neill - Springboard Technologies Ltd  - http://www.springboardtechnologies.com 
----------------------------------------------------------------------------- 
 Notes: 
 
 Simple UDP client demo 
 
} 
 
 
unit UDPClientMain; 
 
interface 
 
uses 
  Windows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2,   stdctrls, 
  SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze, 
  IdComponent, IdUDPBase, IdUDPClient, IdStack, IdUDPServer, IdSocketHandle, 
  ExtCtrls, IdTCPServer, IdTCPConnection, IdTCPClient, Winsock, Variants, ScktComp; 
 
const 
 WM_SOCK=9876; 
 
type 
  TUDPMainForm = class(TForm) 
    SourceGroupBox: TGroupBox; 
    HostNameLabel: TLabel; 
    HostAddressLabel: TLabel; 
    HostName: TLabel; 
    HostAddress: TLabel; 
    PortLabel: TLabel; 
    Port: TLabel; 
    DestinationLabel: TLabel; 
    DestinationAddress: TLabel; 
    BufferSizeLabel: TLabel; 
    BufferSize: TLabel; 
    UDPMemo: TMemo; 
    SendButton: TButton; 
    Button1: TButton; 
    Button2: TButton; 
    LabeledEdit1: TLabeledEdit; 
    LabeledEdit2: TLabeledEdit; 
    LabeledEdit3: TLabeledEdit; 
    LabeledEdit4: TLabeledEdit; 
    Button3: TButton; 
    Button4: TButton; 
    Button5: TButton; 
    Button6: TButton; 
    Button7: TButton; 
    Button8: TButton; 
    Button9: TButton; 
    Button10: TButton; 
    Button11: TButton; 
    Button12: TButton; 
    Button13: TButton; 
    Button14: TButton; 
    LabeledEdit5: TLabeledEdit; 
    Button15: TButton; 
    Button16: TButton; 
    procedure FormCreate(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure Button4Click(Sender: TObject); 
    procedure Button5Click(Sender: TObject); 
    procedure Button6Click(Sender: TObject); 
    procedure Button7Click(Sender: TObject); 
    procedure Button8Click(Sender: TObject); 
    procedure Button9Click(Sender: TObject); 
    procedure Button10Click(Sender: TObject); 
    procedure Button11Click(Sender: TObject); 
    procedure Button12Click(Sender: TObject); 
    procedure Button13Click(Sender: TObject); 
    procedure Button14Click(Sender: TObject); 
    procedure Button15Click(Sender: TObject); 
    procedure Button16Click(Sender: TObject); 
    procedure SendButtonClick(Sender: TObject); 
  private 
    { Private declarations } 
    procedure SendData; 
    procedure puchMsg_proc(num,len:word;code:byte); 
    function modbus_CRC(pp:Pbytearray;flag : boolean) : boolean; // quantity of bytes in message 
    procedure WMSOCKET(var Msg:TMessage); Message WM_SOCK; 
    function open : boolean; 
  public 
    { Public declarations } 
    s :TSocket; 
  end; 
 
//procedure Receive(server :TSocket);stdcall; 
 
var 
  UDPMainForm: TUDPMainForm; 
  puchMsg : array[0..1023] of byte; //按信息的字节数计算CRC 
  Number:word; 
 
 
//高位字节表 
// Table of CRC values for high-order byte 
 
const auchCRCHi:array[0..255] of byte = ( 
  $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, 
  $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, 
  $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, 
  $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, 
  $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, 
  $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, 
  $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, 
  $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, 
  $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, 
  $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, 
  $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, 
  $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, 
  $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, 
  $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, 
  $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, 
  $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, 
  $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, 
  $40 
) ; 
 
//低位字节表 
// Table of CRC values for low-order byte 
 
const auchCRCLo:array[0..255] of byte = ( 
  $00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06, $07, $C7, $05, $C5, $C4, 
  $04, $CC, $0C, $0D, $CD, $0F, $CF, $CE, $0E, $0A, $CA, $CB, $0B, $C9, $09, 
  $08, $C8, $D8, $18, $19, $D9, $1B, $DB, $DA, $1A, $1E, $DE, $DF, $1F, $DD, 
  $1D, $1C, $DC, $14, $D4, $D5, $15, $D7, $17, $16, $D6, $D2, $12, $13, $D3, 
  $11, $D1, $D0, $10, $F0, $30, $31, $F1, $33, $F3, $F2, $32, $36, $F6, $F7, 
  $37, $F5, $35, $34, $F4, $3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE, $FA, $3A, 
  $3B, $FB, $39, $F9, $F8, $38, $28, $E8, $E9, $29, $EB, $2B, $2A, $EA, $EE, 
  $2E, $2F, $EF, $2D, $ED, $EC, $2C, $E4, $24, $25, $E5, $27, $E7, $E6, $26, 
  $22, $E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60, $61, $A1, $63, $A3, $A2, 
  $62, $66, $A6, $A7, $67, $A5, $65, $64, $A4, $6C, $AC, $AD, $6D, $AF, $6F, 
  $6E, $AE, $AA, $6A, $6B, $AB, $69, $A9, $A8, $68, $78, $B8, $B9, $79, $BB, 
  $7B, $7A, $BA, $BE, $7E, $7F, $BF, $7D, $BD, $BC, $7C, $B4, $74, $75, $B5, 
  $77, $B7, $B6, $76, $72, $B2, $B3, $73, $B1, $71, $70, $B0, $50, $90, $91, 
  $51, $93, $53, $52, $92, $96, $56, $57, $97, $55, $95, $94, $54, $9C, $5C, 
  $5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B, $99, $59, $58, $98, $88, 
  $48, $49, $89, $4B, $8B, $8A, $4A, $4E, $8E, $8F, $4F, $8D, $4D, $4C, $8C, 
  $44, $84, $85, $45, $87, $47, $46, $86, $82, $42, $43, $83, $41, $81, $80, 
  $40 
) ; 
 
 
implementation 
 
const 
  HOSTNAMELENGTH = 80; 
  RECIEVETIMEOUT = 500; // milliseconds 
  buflen = 1024 ; 
 
{$R *.DFM} 
 
procedure TUDPMainForm.WMSOCKET(var Msg:TMessage);           //事件处理 
var 
  recbuf :array[0..buflen -1] of byte; 
  ra :Tsockaddr;//TSockAddr; 
  rs:string; 
  i,n:integer; 
//  v:word;           //16bit 
  v1:Psingle;         //32bit浮点数 
  v2:Plongword;       //32bit 
  v3:pword; 
  nnn:TSystemTime; 
  date:Tdatetime; 
begin 
  case WSAGetSelectEVENT(msg.LParam) of 
    FD_Read: 
      begin 
        i:=sizeof(ra); 
 
        recvfrom(s,recbuf,buflen,0,ra,i); 
 
        rs := inet_ntoa(ra.sin_addr)+' Port:'+inttostr(ntohs(ra.sin_port)) ; 
        UDPMemo.Lines.Add(rs); 
 
        v3:=@recbuf[4]; 
        n:=v3^+6; 
        rs:='接收 '; 
        for i:=0 to n-1 do rs:=rs+inttohex(recbuf[i],2)+' '; 
 
        if not UDPMainForm.modbus_CRC(@recbuf,true) then 
        begin 
          showmessage('数据错误!'); 
          exit; 
        end; 
 
        case recbuf[7] of 
          $f2:     //读取时间 
          begin 
            nnn.wYear  := recbuf[n-3]+2000; 
            nnn.wMonth := recbuf[n-4]; 
            nnn.wDay := recbuf[n-5]; 
            nnn.wHour := recbuf[n-6]; 
            nnn.wMinute := recbuf[n-7]; 
 
            v3:=@recbuf[n-9]; 
            nnn.wSecond := v3^ div 1000; 
            nnn.wMilliseconds := v3^ mod 1000; 
 
            date:=systemtimetodatetime(nnn); 
            rs:=rs+' 时间:'+FormatDateTime('yyyy-mm-dd hh:mm:ss.zzz',date); 
          end; 
          $2:      //遥测 
          begin 
            v3:=@recbuf[8]; 
            rs:=rs+' 起始地址:'+inttostr(v3^)+' '+' 值:'; 
            v3:=@recbuf[10]; 
            i:=V3^; 
            for n:=0 to i-1 do 
            begin 
              v3:=@recbuf[12+n*2]; 
              if (v3^ and $8000)<>0 then rs:=rs+inttostr(-1*(v3^ and $7fff))+' ' 
              else rs:=rs+inttostr(v3^)+' '; 
            end; 
          end; 
          $3:      //遥脉 
          begin 
            v3:=@recbuf[8]; 
            rs:=rs+' 起始地址:'+inttostr(v3^)+' '+' 值:'; 
            v3:=@recbuf[10]; 
 
            for n:=0 to v3^-1 do 
            begin 
              v2:=@recbuf[12+n*4]; 
              rs:=rs+inttostr(v2^)+' '; 
            end; 
          end; 
          $17:     //定值 
          begin 
            v3:=@recbuf[8]; 
            rs:=rs+' 起始地址:'+inttostr(v3^)+' '+' 值:'; 
            v3:=@recbuf[10]; 
 
            for n:=0 to v3^-1 do 
            begin 
              v1:=@recbuf[12+n*4]; 
              rs:=rs+format('%f',[v1^])+' '; 
            end; 
          end; 
          else 
        end; 
        UDPMemo.Lines.Add(rs); 
     end; 
  end; 
end; 
 
function TUDPMainForm.open : boolean; 
var 
  sa :TWSAData; 
  wsstatus :Integer; 
  ad :sockaddr_in; 
//  threadid :DWORD; 
//  SS:string; 
  no:boolean; 
begin 
   wsstatus := WSAStartup($0202,sa); 
   if  wsstatus <> 0 then 
   begin 
     ShowMessage('socket初始化出错!'); 
     result:=false; 
 
     Exit; 
   end; 
 
   s := socket(AF_INET,SOCK_DGRAM,IPPROTO_IP); 
   if s = INVALID_SOCKET then 
   begin 
     ShowMessage('建立socket出错!'); 
     WSACleanup; 
     result:=false; 
     Exit; 
   end; 
 
   ad.sin_port := htons(8003); 
   ad.sin_family := AF_INET; 
   ad.sin_addr.S_addr := INADDR_ANY; 
   wsstatus := bind(s,ad,SizeOf(ad)); 
 
//   ad.sin_family := AF_INET; 
//   ad.sin_port := htons(8003); 
//   ss:='192.168.1.'+inttostr(180+strtointdef(labelededit1.text,1)); 
//   ad.sin_addr.S_addr := inet_addr(PChar(ss)); 
//   wstates := connect(s,ad,SizeOf(ad)); 
   if wsstatus <> 0 then 
   begin 
     ShowMessage('连接错误'); 
     WSACleanup; 
     result:=false; 
     Exit; 
   end; 
 
   no:=true; 
 
   setsockopt(s,SOL_SOCKET,SO_BROADCAST,@no,sizeof(no));  
 
   WSAAsyncSelect(s,handle,WM_SOCK,FD_READ or FD_ACCEPT);   //事件处理 
 
//   CreateThread(nil,0,@Receive,Pointer(s),0,threadid);   //流处理 
   result:=true; 
end; 
 
//flag:false计算CRC;true为比较CRC 
function TUDPMainForm.modbus_CRC(pp:Pbytearray;flag : boolean) : boolean; 
var 
  uIndex:byte; //把CRC表 
  i,usDataLen: integer; 
  j,uchCRCHi, uchCRCLo:byte ; 
begin 
  result:=true; 
  uchCRCHi := $FF ; // 初始化高字节 
  uchCRCLo := $FF ; // 初始化低字节 
 
  usDataLen := pp[5] *$100 + pp[4] + 6; 
 
  for i:=6  to usDataLen-3 do //通过数据缓冲器 6 
  begin 
    j:=pp[i]; 
    uIndex := uchCRCHi xor j; //计算CRC 
    uchCRCHi := uchCRCLo xor auchCRCHi[uIndex] ; 
    uchCRCLo := auchCRCLo[uIndex] ; 
  end; 
 
  if not flag then 
  begin 
    pp[usDataLen-2] := uchCRCHi; 
    pp[usDataLen-1] := uchCRCLo; 
  end 
  else 
    if (pp[usDataLen-2] = uchCRCHi) and (pp[usDataLen-1] = uchCRCLo) then result:=true; 
end; 
 
procedure TUDPMainForm.puchMsg_proc(num,len:word;code:byte); // quantity of bytes in message 
var 
  i:integer; 
begin 
  puchMsg[0] := Number and $ff; 
  puchMsg[1] := (Number and $ff00) shr 8; 
  puchMsg[2] := $00;    //协议标识 
  puchMsg[3] := $00;    //协议标识 
  puchMsg[4] := len and $ff;    //长度字段低字节 
  puchMsg[5] := (len and $ff00) shr 8;    //长度字段高字节 
  puchMsg[6] := strtointdef(labelededit1.text,1);   //网关地址 
  puchMsg[7] := code;    //功能代码:按字节查询遥信 
 
  case code of 
    $2: 
      begin 
        i:=strtointdef(labelededit2.text,1);  //装备号 
        i:= (i-1)*16*2; 
      end; 
    $3: 
      begin 
        i:=strtointdef(labelededit2.text,1);  //装备号 
        i:= (i-1)*32*4; 
      end; 
    $5: 
      begin 
        i:=strtointdef(labelededit2.text,1);  //装备号 
        i:= (i-1)*50+strtointdef(labelededit5.text,1); 
      end; 
    $10: 
        i:=strtointdef(labelededit2.text,1);  //装备号 
    $0b: 
      begin 
        i:=strtointdef(labelededit2.text,1);  //装备号 
        i:= (i-1)*10+strtointdef(labelededit5.text,1); 
      end; 
    $07: 
      begin 
        i:=strtointdef(labelededit2.text,1);  //装备号 
        i:=(i-1)*128; 
      end 
    else 
      i := strtointdef(labelededit3.text,0);  //起始地址 
  end; 
 
  puchMsg[8] := i and $ff;        //起始寄存器地址低字节 
  puchMsg[9] := (i and $ff00) shr 8; //起始寄存器地址高字节 
 
//  i := strtointdef(labelededit2.text,1);  //数量 
 
  puchMsg[10] := num and $ff;   //寄存器数量低字节 
  puchMsg[11] := (num and $ff00) shr 8;   //寄存器数量高字节 
end; 
 
procedure TUDPMainForm.SendData; // quantity of bytes in message 
var 
  ThisMessage:string; 
  i,sendLen:integer; 
  ra : TSockAddr;//sockaddr_in; 
begin 
  ThisMessage := '发送 '; 
 
  for i:=0 to puchMsg[4]+5 do 
    ThisMessage := ThisMessage+inttoHex(puchMsg[i],2)+' '; 
 
  UDPMemo.Lines.Add(ThisMessage); 
 
  ThisMessage:='192.168.1.'+inttostr(180+strtointdef(labelededit1.text,1)); 
  ra.sin_addr.S_addr := inet_addr(PChar(ThisMessage)); 
  ra.sin_port := htons(8003); 
  ra.sin_family := AF_INET; 
 
  sendLen := sendto(s,puchMsg,buflen,0,ra,sizeof(ra)); 
//  sendLen := send(s,puchMsg,buflen,0);      //,0,ra,sizeof(ra)); 
 
  if sendLen < 0 then 
  begin 
    ShowMessage('发送出错'+inttostr(getlasterror)); 
    WSACleanup; 
    exit; 
  end; 
 
  Number := Number + 1; 
end; 
 
 
procedure TUDPMainForm.FormCreate(Sender: TObject); 
begin 
  open;     //建立网关链接 
end; 
 
//按字节查询遥信 
procedure TUDPMainForm.Button2Click(Sender: TObject); 
begin 
  puchMsg_proc(strtointdef(labelededit4.text,1),8,1);   //功能码:$1 
 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button3Click(Sender: TObject); 
begin 
  self.UDPMemo.Clear; 
end; 
 
//按位字节查询遥信 
procedure TUDPMainForm.Button1Click(Sender: TObject); 
begin 
  puchMsg_proc(strtointdef(labelededit4.text,1),8,4);   //功能码:$4 
 
  modbus_CRC(@puchMsg,false); 
 
  sendData; 
end; 
 
//遥测 
procedure TUDPMainForm.Button4Click(Sender: TObject); 
begin 
  puchMsg_proc(strtointdef(labelededit4.text,1),8,2);    //功能码:$2 
 
  modbus_CRC(@puchMsg,false); 
 
  senddata; 
end; 
 
procedure TUDPMainForm.Button5Click(Sender: TObject); 
begin 
  puchMsg_proc(strtointdef(labelededit4.text,1),8,3);  //功能码:$3 
 
  modbus_CRC(@puchMsg,false); 
 
  senddata; 
end; 
 
procedure TUDPMainForm.Button6Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);     //功能码:$5 
 
  puchMsg[12] := $33;   //遥合功能码低字节        成功返回码 :$55 
  puchMsg[13] := $f5;   //遥合功能码高字节        成功返回码 :$f5 
 
  modbus_CRC(@puchMsg,false); 
 
  sendData; 
end; 
 
procedure TUDPMainForm.Button7Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);  //功能码:$5 
 
  puchMsg[12] := $33;   //遥分功能码低字节    成功返回码 :$55 
  puchMsg[13] := $05;   //遥分功能码高字节    成功返回码 :$05 
 
  modbus_CRC(@puchMsg,false); 
 
  sendData; 
end; 
 
procedure TUDPMainForm.Button8Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);     //功能码:$5 
 
  puchMsg[12] := $33;   //遥合执行功能码低字节   成功返回码 :$55 
  puchMsg[13] := $fa;   //遥合执行功能码高字节   成功返回码 :$fa 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button9Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);       //功能码:$5 
 
  puchMsg[12] := $33;   //遥分执行功能码低字节     成功返回码 :$55 
  puchMsg[13] := $0a;   //遥分执行功能码高字节     成功返回码 :$0a 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button10Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);     //功能码:$5 
 
  puchMsg[12] := $33;   //遥合取消功能码低字节      成功返回码 :$55 
  puchMsg[13] := $fc;   //遥合取消功能码高字节      成功返回码 :$fc 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button11Click(Sender: TObject); 
begin 
  puchMsg_proc(1,$a,5);       //功能码:$5 
 
  puchMsg[12] := $33;   //遥分取消功能码低字节      成功返回码 :$55 
  puchMsg[13] := $0c;   //遥分取消功能码高字节      成功返回码 :$0c 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button12Click(Sender: TObject); 
begin 
  puchMsg_proc(1,8,$10);      //功能码:$10 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button13Click(Sender: TObject); 
var 
  SysTime: TsystemTime; 
  i:word; 
begin 
  puchMsg_proc(1,$f,$12);     //功能码:$12 
 
  GetLocalTime(SysTime); 
 
  i := systime.wMilliseconds+systime.wSecond*1000; 
 
  puchMsg[12] := (i and $ff);   //毫秒低字节 
  puchMsg[13] := (i and $ff00) shr 8;   //毫秒高字节 
 
  puchMsg[14] := systime.wMinute;   //分 
  puchMsg[15] := systime.wHour;   //时 
  puchMsg[16] := systime.wDay;   //日 
  puchMsg[17] := systime.wMonth;   //月 
  puchMsg[18] := systime.wYear-2000;   //年 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button14Click(Sender: TObject); 
begin 
  puchMsg_proc(1,8,$F2);      //功能码:$f2 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button15Click(Sender: TObject); 
begin 
  puchMsg_proc(1,8,$0b);      //功能码:$10 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.Button16Click(Sender: TObject); 
begin 
  puchMsg_proc($80,8,$07);      //功能码:$07 
 
  modbus_CRC(@puchMsg,false); 
 
  SendData; 
end; 
 
procedure TUDPMainForm.SendButtonClick(Sender: TObject); 
var 
  tt:array[0..3] of byte; 
  f:^Single; 
//  p1,p2:Pbyte; 
//  i:integer; 
  s:string; 
begin 
//  f:=110.0; 
  tt[0]:=$0; 
  tt[1]:=$0; 
  tt[2]:=$c8; 
  tt[3]:=$42; 
//  p1:=@f; 
//  p2:=p1; 
//  copymemory(@tt[0],p1,sizeof(p1)); 
//  move(p2,p1,sizeof(p1)); 
//  for i:=0 to 3 do 
//  begin 
//    p2^:=p1^; 
//    p1:=pointer(integer(p1)+1); 
//    p2:=pointer(integer(p2)+1); 
//  end; 
 
//  s:=''; 
//  for i:=0 to 3 do 
//  begin 
//    s:=s+inttohex(p2^,2)+' '; 
//    p2:=pointer(integer(p2)+1); 
//  end; 
  f:=@tt[0]; 
  s:=format('%f',[f^]); 
  self.UDPMemo.Lines.Add(s); 
end; 
 
{ 
procedure Receive(server :TSocket);stdcall;       //流接收数据 
var 
  recbuf:array[0..buflen -1] of byte; 
  rtn :Integer; 
  rs :string; 
  n,i:integer; 
  nnn:TSystemTime; 
begin 
  while True do 
  begin 
    rtn := recv(server,recbuf,buflen,0); 
 
    if rtn < 1 then 
    begin 
      ShowMessage('接收出错'+inttostr(getlasterror)); 
      continue; 
    end; 
 
    if not UDPMainForm.modbus_CRC(@recbuf,true) then continue; 
 
    n:=recbuf[4]+recbuf[5]*$100+6; 
    rs:='接收 '; 
    for i:=0 to n-1 do 
        rs:=rs+inttohex(recbuf[i],2)+' '; 
    if recbuf[7]=$f2 then 
    begin 
      nnn.wYear  := recbuf[n-3]+2000; 
      nnn.wMonth := recbuf[n-4]; 
      nnn.wDay := recbuf[n-5]; 
      nnn.wHour := recbuf[n-6]; 
      nnn.wMinute := recbuf[n-7]; 
      nnn.wSecond := (recbuf[n-8]*$100+recbuf[n-9]) div 1000; 
      nnn.wMilliseconds := (recbuf[n-8]*$100+recbuf[n-9]) mod 1000; 
      rs:=rs+'时间:'+inttostr(nnn.wyear)+'-'+inttostr(nnn.wMonth)+'-'+inttostr(nnn.wDay) 
        +' '+inttostr(nnn.wHour)+':'+inttostr(nnn.wMinute)+':'+inttostr(nnn.wSecond)+'.'+inttostr(nnn.wMilliseconds); 
    end; 
    UDPMainForm.UDPMemo.Lines.Add(rs); 
  end; 
end;       } 
 
end.