系统工作方式描述:
   客户端PC上的控制程序Client用于向检测站服务器端的Server程序传送数据。数据传输采用帧格式传递。格式如下:
   帧起始符(1字节)+
   数据包长度(4字节)+
   数据包(可变长度字节)+
   数据包结束符(1字节)+
   帧校验符(1字节)+
   帧结束符(1字节)
其中各部分的含义为:
①  帧起始符 :
   帧起始符有两种选择,若为#$02(即16进制数0x02所对应的字符,下同),则表示传递的是测试数据,若为#$03, 则表示传递的是位置信息。
②  数据包长度:
   数据包长度为4字符长度,如长度为40个字节则用“0040”表示。
③  数据包:
   数据包分两类,一类为位置信息,它的格式为:
   当前触发位址(1字节)+设备号(16字节)+该设备测试次数(2字节)
   其中当前触发位址字符为‘1’、‘2’、‘3’、‘4’、‘5’。 如果只有四个位置,则最大数字字符为‘5’,依次类推。
   另一类为测试数据打包串。
④  数据结束符
   固定为:#$17
⑤  帧校验符:
STX^…^ETB
   checksum=帧起始符xor…xor数据包结束符。即数据包结束符及以前所有单字节的异或和。如果checksum等于#$0 或 ‘$’,则将checksum替换为#$18。
⑥  帧结束符。
   固定为:‘$‘
----------
     请问按上面的通讯协议要求,通过delphi7的winsoctet该如何实现呢?

解决方案 »

  1.   

    很简单啊
    弄个char数组
    按照协议往数组里填充数据,
    再把数组发送就是了
      

  2.   

    我把我写的代码发在这里,你帮我看下吧?  发过去总是报"数据校验错"
    我对应于通讯协议,先定义了结构如下:
      type
            TMyPack   =   packed   Record
                  FrameStart:Byte;
                  DataLen:Longword ;
                  Body:Array[0..65535] of Char;
                  DataEnd:Byte;
                  FrameCheck:Byte;
                  FrameEnd:Byte;
            end;然后在发送按钮做了如下处理
    procedure TFrmMain.BitBtn1Click(Sender: TObject);
    var
        sBody:String;
        myPack:^TMyPack;
    begin
            sBody   :=   Trim(memSend.Text);
            New(myPack);
            myPack.FrameStart := 2;
            myPack.DataEnd := 17;
            myPack.FrameCheck := 18;
            myPack.DataLen   :=  8192 ;//Length(sBody);
            myPack.FrameEnd   :=   $;
            strpcopy(myPack.Body,sBody);        Try
                  Send(xl_socket,myPack,sizeof(myPack),0);
            Finally
                  if   myPack   <>   nil   then
                  begin
                        FreeMem(myPack,SizeOf(myPack));              end;
            end;end;
      

  3.   

    很明显你没有计算校验和checksum=帧起始符xor…xor数据包结束符。即数据包结束符及以前所有单字节的异或和。如果checksum等于#$0 或 ‘$’,则将checksum替换为#$18。
      

  4.   

    checksum=帧起始符xor…xor数据包结束符。即数据包结束符及以前所有单字节的异或和。如果checksum等于#$0 或 ‘$’,则将checksum替换为#$18。
    这句看不懂吗?
      

  5.   

    a:array [0..1024] of char;
    a[0]:=帧起始符(1字节)
    a[1]:=数据包长度;
    a[2]:=数据包长度;
    a[3]:=数据包长度;
    a[4]:=数据包长度;
    a[5]:=数据包内容;
    ..
    .
    a[n]:=数据包内容;
    a[n+1]:=数据包结束符(1字节);
    a[n+2]:=帧校验符(1字节);
    a[n+3]:=帧结束符(1字节) 
    帧校验符计算方式如下:
    var chesum:char;
        i:integer;
    chesum:=#0;
    for i:=0 to n do  //到数据包结束符截止
    begin
      chesum:=chesum xor a[i];
    end;
    a[n+2]:=chesum;
      

  6.   

    Kvci, 你好!  按照你的提示修改代码如下,不知道对否?  但是在编译的时候到"chesum:=chesum xor aa[i];"  这句就编不过去了,不晓得是怎么回事?procedure TFrmMain.BitBtn1Click(Sender: TObject);
    var
        i,n: Integer;
        chesum:char;
        aa:array [0..1024] of char;
    begin    n:=Length(Trim(memSend.Text));
        aa[0]:=#2;
        aa[1]:=#0;
        aa[2]:=#0;
        aa[3]:=#4;
        aa[4]:=#0;
        aa[5]:=PChar(Trim(edtSend.Text))^;
        aa[n+1]:=#17;
        chesum:=#0;
        for i:=0 to n do  //到数据包结束符截止
        begin
            chesum:=chesum xor aa[i];
        end;
        if ((chesum=#$0) or (chesum=#$0)) then
        chesum:=#$18;
        aa[n+2]:=chesum;
        aa[n+3]:=#$;
        Try
            Send(xl_socket,aa,sizeof(aa),0);
        Finally
            ShowMessage('发送异常,请检查!');
        end;
    end;
      

  7.   

    应该是类型的问题吧,xor运算符应该操作整数类型吧,换成byte试试
      

  8.   

    Logical (bitwise) operators 
    Operator Operation Operand types Result type Examples
    not bitwise negation integer integer not X
    and bitwise and integer integer X and Y
    or bitwise or integer integer X or Y
    xor bitwise xor integer integer X xor Y
    shl bitwise shift left integer integer X shl 2
    shr bitwise shift right integer integer Y shr I
    这是帮助里对位运算的介绍,你参考下
      

  9.   

    aa[5]:=PChar(Trim(edtSend.Text))^; 
    这里不是这样的
    你要搞清楚一下字符数组和string的区别