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 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("发送失败");
}
}
}
}
}
tcpclient类代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MTWS.Net.SocketClient
{
class TCPClient
{
//客户端socket
Socket ClientSocket;
IPEndPoint ipend;
public TCPClient()
{
}
~TCPClient()
{
}
public int ConnectServer(string IP, int Port)
{
int ret = 0;
ipend = new IPEndPoint(IPAddress.Parse(IP), Port);
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
ClientSocket.Connect(ipend);
ret = 1;
}
catch (SocketException ex)
{
ret = 0;
//throw new Exception(ex.Message);
}
return ret;
}
public bool IsConnected()
{
return ClientSocket.Connected;
}
public int SendMsg(byte[] Msg)
{
if (IsConnected())
return ClientSocket.Send(Msg, Msg.Length, SocketFlags.None);
else
return -1;
}
public int RecvMsg(byte[] Msg)
{
int bufLen = 0;
bufLen = Msg.Length;
if (IsConnected())
return ClientSocket.Receive(Msg, bufLen, SocketFlags.None);
else
return -1;
}
}
}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdTCPServer1.DefaultPort := 3578;
IdTCPServer1.Active := True;
//ShowMessage('ok');
except
on e: Exception do
ShowMessage(e.Message);
end;
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
//while not Terminated do begin
if AThread.Connection.Connected then begin
//ShowMessage('aa');
FillChar(msgBody, SizeOf(TmsgHead), 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(ntohl(msgBody.body)); //如果不加ntohl数据比较大,好像一个//地址,加上以后,出现高位丢失问题只限于256以下的数字,如果c#发256,delphi显示0,以此类似,到//了512,又显示0,513显示1
end;
//end;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
//ShowMessage(AThread.Connection.Socket.Binding.PeerIP);
end;
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 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("发送失败");
}
}
}
}
}
tcpclient类代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MTWS.Net.SocketClient
{
class TCPClient
{
//客户端socket
Socket ClientSocket;
IPEndPoint ipend;
public TCPClient()
{
}
~TCPClient()
{
}
public int ConnectServer(string IP, int Port)
{
int ret = 0;
ipend = new IPEndPoint(IPAddress.Parse(IP), Port);
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
ClientSocket.Connect(ipend);
ret = 1;
}
catch (SocketException ex)
{
ret = 0;
//throw new Exception(ex.Message);
}
return ret;
}
public bool IsConnected()
{
return ClientSocket.Connected;
}
public int SendMsg(byte[] Msg)
{
if (IsConnected())
return ClientSocket.Send(Msg, Msg.Length, SocketFlags.None);
else
return -1;
}
public int RecvMsg(byte[] Msg)
{
int bufLen = 0;
bufLen = Msg.Length;
if (IsConnected())
return ClientSocket.Receive(Msg, bufLen, SocketFlags.None);
else
return -1;
}
}
}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdTCPServer1.DefaultPort := 3578;
IdTCPServer1.Active := True;
//ShowMessage('ok');
except
on e: Exception do
ShowMessage(e.Message);
end;
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
//while not Terminated do begin
if AThread.Connection.Connected then begin
//ShowMessage('aa');
FillChar(msgBody, SizeOf(TmsgHead), 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(ntohl(msgBody.body)); //如果不加ntohl数据比较大,好像一个//地址,加上以后,出现高位丢失问题只限于256以下的数字,如果c#发256,delphi显示0,以此类似,到//了512,又显示0,513显示1
end;
//end;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
//ShowMessage(AThread.Connection.Socket.Binding.PeerIP);
end;
end.
C#中的结构体数组应该如何定义和赋值啊
这个要看服务端结构的对齐方式了
在结构上加上一行试试
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TMsgHeadInfo
{
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
public int SendInt;
}
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 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("发送失败");
}
}
}
}
}
tcpclient类代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MTWS.Net.SocketClient
{
class TCPClient
{
//客户端socket
Socket ClientSocket;
IPEndPoint ipend;
public TCPClient()
{
}
~TCPClient()
{
}
public int ConnectServer(string IP, int Port)
{
int ret = 0;
ipend = new IPEndPoint(IPAddress.Parse(IP), Port);
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
ClientSocket.Connect(ipend);
ret = 1;
}
catch (SocketException ex)
{
ret = 0;
//throw new Exception(ex.Message);
}
return ret;
}
public bool IsConnected()
{
return ClientSocket.Connected;
}
public int SendMsg(byte[] Msg)
{
if (IsConnected())
return ClientSocket.Send(Msg, Msg.Length, SocketFlags.None);
else
return -1;
}
public int RecvMsg(byte[] Msg)
{
int bufLen = 0;
bufLen = Msg.Length;
if (IsConnected())
return ClientSocket.Receive(Msg, bufLen, SocketFlags.None);
else
return -1;
}
}
}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdTCPServer1.DefaultPort := 3578;
IdTCPServer1.Active := True;
//ShowMessage('ok');
except
on e: Exception do
ShowMessage(e.Message);
end;
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
//while not Terminated do begin
if AThread.Connection.Connected then begin
//ShowMessage('aa');
FillChar(msgBody, SizeOf(TmsgHead), 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(ntohl(msgBody.body)); //如果不加ntohl数据比较大,好像一个//地址,加上以后,出现高位丢失问题只限于256以下的数字,如果c#发256,delphi显示0,以此类似,到//了512,又显示0,513显示1
end;
//end;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
//ShowMessage(AThread.Connection.Socket.Binding.PeerIP);
end;
end.
C#中的结构体数组应该如何定义和赋值啊
这个要看服务端结构的对齐方式了
在结构上加上一行试试
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TMsgHeadInfo
{
//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char MsgCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public char[] MsgType;
public byte Sender;
public int SendInt;
}
(2)相互关系:A 客户端与应用服务器关系
首先建立连接实现数据增删查改操作这个很简单。其次客户端注册服务器事件,接收由服务器主动推送过来的实时数据。
B 设备终端与设备终端数据处理服务器关系
设备终端与设备终端处理服务器建立连接,实时上传所采集的数据,在进行加工处理后向应用服务器提交。
C 设备数据处理服务器与应用服务器关系
设备服务器向应用服务器建立连接,上传数据,应用服务器接收该数据,并向数据库中写入,同时向已登陆的客户端实时主动推送该数据。这里非常重要,也是问题的关键点。
D 应用服务器与数据库的关系
首先应用服务器作为客户端与数据库中间件,响应客户端的增删查改请求,这个很简单。其二应用服务器能够将设备数据处理服务器所上传的数据实时写入数据库,并向已注册客户端实时推送。