[StructLayout(LayoutKind.Explicit)] struct record { public long mainid; public long subid; public long roomip; [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] public long[] reserved; public long datalen; [MarshalAs(UnmanagedType.ByValArray, SizeConst=PACKET_SIZE-32-1)] public char[] data; }
大致就这样,具体的你再调整下。
我想你看了我的代码应该能明白一些,你只是缺乏遇到数组该怎么定义的问题。
说明:有个delphi服务程序,会检测其他机器发送过来的udp数据,然后做个显示,目前有个delphi客服端发送能成功接收并显示,但本人写了个c#的客户端程序,能接收到,但显示数据不对,请高手看看。
首先请看delphi客户端程序代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient, StdCtrls,
IdUDPServer, IdSocketHandle;
const PACKET_SIZE = 4096;
const HOST_PORT = 9527;
type
PPACK_INFO = ^TPACK_INFO;
TPACK_INFO = record //字节存储采用主机顺序
mainid: DWORD; //主消息号
subid: DWORD; //子消息号
roomip: DWORD; //保存此消息是哪个包厢IP发出
reserved: array[0..3] of DWORD; //预留
datalen: DWORD; //正文长度
data: array[0..PACKET_SIZE-32-1] of char; //正文内容
end;
//发送数据函数 向服务器192.168.1.11端口9527发送主消息:0x01,子消息:0x01,包厢ip:192.168.1.205
var
strServerIP: string;
strRoomIP: string;
pack_info: TPACK_INFO;
begin
strServerIP := trim(192.168.1.11);//服务器IP
strRoomIP := trim(192.168.1.205);//包厢IP
ZeroMemory(@pack_info, sizeof(TPACK_INFO));
pack_info.mainid := $01;//主消息
pack_info.subid := $01;//子消息
CopyMemory(@pack_info.data[0], @strRoomIP[1], Length(strRoomIP));
pack_info.datalen := Length(pack_info.data);
IdUDPClient1.Port := HOST_PORT;
IdUDPClient1.Host := strServerIP;
IdUDPClient1.SendBuffer(pack_info, 32+pack_info.datalen);
end;
服务器端接收到数据,并显示为:[01][01]192.168.1.205
问题来来了,如何写一个c#客户端程序向服务器192.168.1.11端口9527发送主消息:0x01,子消息:0x01,包厢ip:192.168.1.205 然后显示为:[01][01]192.168.1.205
本人写的c# 客户端代码:
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
namespace client
{
public partial class send : Form
{
private UdpClient Client;//定义客户端,网络终端
private IPEndPoint rePoint;
const int HOST_PORT = 9527; //服务器端口
public send()
{
InitializeComponent();
}
private void btnOpen_Click(object sender, EventArgs e)
{
Client = new UdpClient();//本机监听端口确定
IPAddress adress = IPAddress.Parse("192.168.1.11");//务器IP
rePoint = new IPEndPoint(adress, HOST_PORT);
string strdata = "[0x01][0x01]192.168.1.205";
byte[] data = Encoding.Unicode.GetBytes(strdata);
Client.Send(data, data.Length, rePoint);
}
}
}
改代码调试,然后发送:
delphi服务程序也是能接收到数据的,但是数据显示为:[01][01]5而不是:[01][01]192.168.1.205
现在搞不明白c#那个数据报data应该如何写,才能让delphi服务器接收到并解释为:[01][01]192.168.1.205
你这个结构体我用过呀,但是还是实现不了上面这个问题!
结构体的字体说明:
mainid //主消息号
subid //子消息号
roomip //保存此消息是哪个包厢IP发出
reserved //预留
datalen //正文长度
data //正文内容
这两个没问题mainid,subid ,但是roomip保存的ip地址,这个不知道怎么处理了!
@tofy: 你这个IP地址是一个DWORD,也就是一个LONG。
IP地址我么通常是xxx.xxx.xxx.xxx的格式,其实这个就是一个32位的整数,如果到了IPV6后,就要是48位的整数,而无论是32位还是48位,都在long的范围内(long是64位)。
IP地址就是按字节描述的内容。
比如一个IP地址:1.2.3.4,对应的整数就是:
((1*256 + 2) * 256 + 3) * 256 + 4 。
你要达到常规IP地址的策略,只要另外写一个属性,实现这个转换就好了。