首页 新闻 会员 周边

c#客户端发送udp数据到delphi服务器端,c#数据如何打包发送过去

0
悬赏园豆:50 [待解决问题]

说明:有个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

tofy的主页 tofy | 初学一级 | 园豆:92
提问于:2012-06-22 14:48
< >
分享
所有回答(2)
0

你得到的數據,應該 進行轉換的。c#發送的是byte【】數組。你讀取到的是byte【】,應該先轉換成string,然互毆才能正確。

無限遐想 | 园豆:3740 (老鸟四级) | 2012-06-24 08:34
0

楼主写网络通讯的时候一定要注意字节码顺序,是高位在前还是低位在前。参考资料如下:

字节顺序是多字节数据被存储的顺序。例如,一个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); 

希望对你有所帮助。

归真 | 园豆:605 (小虾三级) | 2012-07-14 19:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册