说明:有个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服务程序也是能接收到数据的,但是数据显示为:[230023][4F004C]0 而不是:[01][01]192.168.1.205
现在搞不明白c#那个数据报data应该如何写,才能让delphi服务器接收到并解释为:[01][01]192.168.1.205
你得到的數據,應該 進行轉換的。c#發送的是byte【】數組。你讀取到的是byte【】,應該先轉換成string,然互毆才能正確。
楼主写网络通讯的时候一定要注意字节码顺序,是高位在前还是低位在前。参考资料如下:
字节顺序是多字节数据被存储的顺序。例如,一个32位的长整型0x12345678跨越4个字节(每个字节8位)。Intel x86机器使用小尾顺序(little-endian),意思是最不重要的字节首先存储。因此,数据 0x12345678在内存中以{0x78、0x56、0x34、0x12}顺序存放。大多数不使用小尾顺序的机器使用大尾顺序(big-endian),即最重要的字节首先存储。同样的值在内存中以{0x12、0x34、0x56、0x78}顺序存放。
因为协议数据要在这些机器间传输,就必须选定其中的一种方式做为标准,否则会引起混淆。TCP/IP协议统一规定使用大尾方式传输数据,也称为网络字节顺序(network byte order)。例如,端口号(它是一个 16位的数字)12345(0x3039)的存储顺序是{0x30、0x39}。
根据你的情况,需要进行组包,伪代码如下:
memorystream ms = new memorystream();
bianryWriter wr = new bianryWriter(ms);
wr.write(obj); //这里的obj是你要写的数值,注意字节顺序,否则服务器解析出来的就是乱码。。。。
最后使用 byte [] data = wr.toArray();
c#转变高低位字节的方式为:
以Int为例:
int i =100; byte[] bytes = BitConverter.GetBytes(i).Reverse().ToArray();
自己移位的方式函数如下:
private int SwapInt32(int int32)
{
return (int32 & 0xFF) < < 24 | (int32 > > 8 & 0xFF) < < 16 |
(int32 > > 16 & 0xFF) < < 8 | (int32 > > 24 & 0xFF);
}
希望对你有所帮助。