您的位置:首页 > 编程语言 > Delphi

socket C#与Delphi互传结构体

2015-09-30 18:26 309 查看
摘要:

      Delphi与C#通过SOCKET通信,互传结构体。好处是可以把协议及要传送的内容封装成一个结构体,一次性发送,不需要再做过多的封包的拆包。封包过程通过的做法是把要发送的内容组成字符串,每个子项内容之间用分隔符隔开,以便客户端收到内容后知道如何拆包。拆包过程就把接收到的字符串再按分隔符分解成多项,并按封包时对应的子项赋值给对应的接收者。整个过程很繁琐,并且不同的开发语言对封包拆包操作的实现的支持也不一样,有的语言方便,有些不方便。

那么采用结构体的好处就显而易见了。其一只需要双方都定义好结构体,发送方转成字节发送,接收方按字节接收,再赋值给结构体变量,就完成了通常意义上封包和拆包过程。其二就是容易控制各项的默认值,各种高级语言对结构体的支持越来越到位、方便了。

正文:

1、C#

        [StructLayout(LayoutKind.Sequential)]//注意此处一定要有此语句

        public struct Body

        {

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]//设置字符的长度,当实际长度不足时,会自动填充0

            public string password;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]//

            public string Tel;

            public int accid;

        }

        

        //转换方法:

        public byte[] StructToBytes<T>(T obj)

        {

            int size = Marshal.SizeOf(obj);

            byte[] bytes = new byte[size]; 

            IntPtr arrPtr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);

            Marshal.StructureToPtr(obj, arrPtr, true);

            return bytes;

        }

      //发送

                    Body body;

                    body.accid = 123412345;

                    body.password = "567890123456";

                    body.Tel = "13526396605abcdefg";

                    data = StructToBytes<Body>(body);

                    ClientSocket.Send(Data, 0, Data.Length, SocketFlags.None);

2、接收Delphi

procedure TMain_Frm.btn14Click(Sender: TObject);

type

  TBody=Packed Record              //包体定义

    password: array[0..15] of char;     //密码

    Tel      :array[0..23] of char;     //手机号

    accid:  integer;                          //编号

  end;

var

  data, recbuff: TIdBytes;

  Body: TBody;

begin

  IdTCPClient1.Connect('192.163.1.132', 5632);

  SetLength(data, 1)

  data[0] := $F0;

  idtcpclnt1.Socket.Write(data);//服务端接收到后返回一个整数

  IdTCPClient1.Socket.ReadBytes(recbuff, SizeOf(Body)); 

  Move( recbuff[0], Body, Length(recbuff) - 1);

  ShowMessage('密码:' + Body.password + #13 + 'tel:' + Body.Tel + #13 + '数字:' + FloatToStr(Body.accid));

end;

接收完成时,就是各项分解并赋值完成时,省去了拆包过程。

3、缺点

    1、所有内容都必须是能够提前知道长度的;

     2、传输的内容相对简单,太复杂的结构传不了。

结束语:

      1、本文重点在于介绍不同语言间如何传递结构体,并无强调结构体优越之意。

      2、本文举例的结构可传递协议,也是基于本人的刷卡交易模块。由于格式固定、内容统一,才易于实现。

      3、感谢网上资料的支持,由于大家的无私奉献,才完成了此功能,在此统一谢过。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket 结构 c#