1,593
社区成员
发帖
与我相关
我的任务
分享
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text;using System.Windows.Forms; using System.Runtime.InteropServices; using MTWS.Net.SocketClient; namespace MTWS.Net.AppCode { public partial class TestTcp : Form { public TestTcp() { InitializeComponent(); } struct TMsgHeadInfo { //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public char MsgCode; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public char[] MsgType; public byte Sender; //public int SendInt; } struct TMsgBody { public TMsgHeadInfo msghead; //假如这里是一个结构体数组时应该如何定义和赋值呢? //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] //public TMsgHeadInfo[] msghead; 这样是不对的 //public TMsgHeadInfo[2] msghead; 这样也不对 //此处到底应该怎样定义与赋值?另外,协议是原来定好了的,肯定不能变了,改协议来解决这个问题的话,就不用提了 public Int32 body; //这里哪个类型对就DELPHI里的integer? } public static byte[] StructToBytes(object structObj) { //得到结构体的大小 int size = Marshal.SizeOf(structObj); //创建byte数组 byte[] bytes = new byte[size]; //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将结构体拷到分配好的内存空间 Marshal.StructureToPtr(structObj, structPtr, false); //从内存空间拷到byte数组 Marshal.Copy(structPtr, bytes, 0, size); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回byte数组 return bytes; } private void TestTcp_Load(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { int ret; TMsgBody msgbody; //TMsgHeadInfo msghead; TCPClient tcp = new TCPClient(); string code = "zp"; string type = "ai"; //string body = "cc"; ret = tcp.ConnectServer("127.0.0.1", 3578); if (ret == 0) { MessageBox.Show("连接服务器失败"); } else { MessageBox.Show("连接服务器成功"); msgbody.msghead.MsgCode = code.ToCharArray(); msgbody.msghead.MsgType = type.ToCharArray(); msgbody.msghead.Sender = 5; msgbody.body = 44;// 服务器端收到后,实际不是44,其他数据类型没有问题 byte[] msg = StructToBytes(msgbody); if (tcp.SendMsg(msg) > 0) { MessageBox.Show("发送成功"); } else { MessageBox.Show("发送失败"); } } } } }
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer; type TChar2 = array[0..1] of Char; TMsgHead=packed record MsgCode, MsgType: TChar2; sender: Byte; senderint: Integer; end; TMsgBody=packed record msgHead: TMsgHead; body: Integer; end; TForm1 = class(TForm) IdTCPServer1: TIdTCPServer; Button1: TButton; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Edit4: TEdit; procedure Button1Click(Sender: TObject); procedure IdTCPServer1Execute(AThread: TIdPeerThread); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin IdTCPServer1.DefaultPort := 3578; IdTCPServer1.Active := True; end; function Min(AValueOne, AValueTwo : Integer): Integer; begin If AValueOne > AValueTwo then begin Result := AValueTwo end //If AValueOne > AValueTwo then else begin Result := AValueOne; end; //..If AValueOne > AValueTwo then end; function PCharToStr(ABuf: array of char; ABufLen: Integer): string; { 将PChar(#0结尾)转换为string }var LenOfStr: Integer; begin LenOfStr := Min(ABufLen, StrLen(ABuf)); if LenOfStr <= 0 then begin Result := ''; end else begin SetLength(Result, LenOfStr); Move(ABuf[0], Result[1], LenOfStr); end; end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); //var msgHead: TMsgHead; var msgBody: TMsgBody; begin if AThread.Connection.Connected then begin FillChar(msgBody, SizeOf(TMsgBody), 0); AThread.Connection.ReadBuffer(msgBody, SizeOf(TMsgBody)); Edit1.Text := PCharToStr(msgBody.msgHead.MsgCode, 2); Edit2.Text := PCharToStr(msgBody.msgHead.MsgType, 2); Edit3.Text := IntToStr(Integer(msgBody.msgHead.sender)); Edit4.Text := IntToStr(msgBody.msgHead.senderint); end; end; end.