已知服务端数据包格式,客户端怎样用Java实现向服务器端(C#写的)接收和发送数据包--急!

zhangfei2007cumt 2012-02-29 04:17:25
请问客户端怎样用Java实现向服务器端(C#写的)接收和发送数据包(及客户端数据包怎么做),服务器端数据包如下:
...全文
334 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangfei2007cumt 2012-03-26
  • 打赏
  • 举报
回复
呵呵,谢谢指点
allan0527 2012-03-13
  • 打赏
  • 举报
回复
public class Packet这个数据包对象是C#里面定义的,客户端当然无法解析。我的意思是用字符串来表示,如json格式的字符串,如:
"packet{MaxLength:32000;InvalidLength:-1;NeedCompressMinLength:100;NoCryptHeaderLength:4...}"
JAVA客户端系统拿到这个字符串后,通过字符串处理,把它转换成JAVA对象。
zhangfei2007cumt 2012-03-08
  • 打赏
  • 举报
回复
如果不加包报头直接发数据流过去的话,服务器端解析出来不对。。。
zhangfei2007cumt 2012-03-05
  • 打赏
  • 举报
回复
首先谢谢你的回答,我也想到用数据流来操作了,但是服务器端现在写好的好像没有数据流相关操作,让我用数据包的方式跟服务器通信。服务器数据包代码如下:
/// <summary>
/// 消息包
/// 内存布局
/// {
/// short PacketFlag;//特殊的值
/// short PacketLength;//消息包的大小,消息不能大于32k
/// int PacketID;//消息包类型id;从这以后的数据可以加密
/// int SerialNumber;//消息包序列号,网络连接每发一个消息包,这个值+1
/// int DispatcherID;//发送者的id
/// //所以消息头的大小是2+2+4+4+4 = 16
/// }
/// </summary>
public class Packet
{
public const short MaxLength = 32000;//32k
public const short InvalidLength = -1;
public const short NeedCompressMinLength = 100;
public const short NoCryptHeaderLength = 4; // 2+2

//消息包标志
public PacketFlag PacketFlag = PacketFlag.Normal;

public int PacketID;

/// <summary>
/// 消息序列号
/// </summary>
public int SerialNumber;
public int DispatcherID;//if id <0 ,is -serverid
protected PacketWriter m_writer;

public Packet(int packetID)
:this(packetID,0)
{

}

public Packet(int packetID,int dispatcherid)
{
PacketID = packetID;
DispatcherID = dispatcherid;
m_writer = new PacketWriter();/*PacketWriter.CreateInstance()*/;
}


private byte[] m_databuffer; //已经有的数据的缓冲
private int m_datalength; //已经有的数据的大小
/// <summary>
/// 消息总长度
/// </summary>
public int Length
{
get{
if (m_databuffer == null)
return Packet.HeaderSize + m_writer.Length;
else
return m_datalength + m_writer.Length;
}
set{
if (m_databuffer == null)
return;
m_datalength = value;
}
}

internal byte[] DataBuffer{
get{
return m_databuffer;
}
set{
m_databuffer = value;
if (m_databuffer != null)
m_datalength = m_databuffer.Length;
}
}

public PacketWriter Writer{
get{
return m_writer;
}
}

internal virtual byte[] ToArray()
{
short packet_length = (short)this.Length;
bool needcreatebuffer = false;
if (DataBuffer == null || m_writer.Length > 0)
needcreatebuffer = true;
if (needcreatebuffer)
{
byte[] newbuffer = new byte[packet_length];
if (m_databuffer != null)
{
Buffer.BlockCopy(m_databuffer, 0, newbuffer, 0, m_datalength);
}
m_databuffer = newbuffer;
}
//写消息头
//ArrayUtility.SetShort(m_databuffer, (short)PacketFlag, 0);
//ArrayUtility.SetShort(m_databuffer, packet_length, 2);
//ArrayUtility.SetInt(m_databuffer, this.PacketID, 4);
//ArrayUtility.SetInt(m_databuffer, this.SerialNumber, 8);
//ArrayUtility.SetInt(m_databuffer, this.DispatcherID, 12);

WriteHead();

if (needcreatebuffer && m_writer.Length > 0)
{
System.Buffer.BlockCopy(m_writer.ToArray(), 0, m_databuffer,
packet_length - m_writer.Length, m_writer.Length);
m_writer.Length = 0;
}
m_datalength = packet_length;

return m_databuffer;
}

protected void WriteHead()
{
//写消息头
ArrayUtility.SetShort(m_databuffer, (short)PacketFlag, 0);
ArrayUtility.SetShort(m_databuffer, (short)this.Length, 2);
ArrayUtility.SetInt(m_databuffer, this.PacketID, 4);
ArrayUtility.SetInt(m_databuffer, this.SerialNumber, 8);
ArrayUtility.SetInt(m_databuffer, this.DispatcherID, 12);
}

/// <summary>
/// 消息头大小 2+2+4+4+4 = 16
/// </summary>
public static int HeaderSize
{
get
{
return 16;
}
}

public void Reset()
{
DataBuffer = null;
Writer.Clear();
}

}

请问我用数据包的方式要怎样做呢?
allan0527 2012-03-05
  • 打赏
  • 举报
回复
TCP 的异构系统通信,只能通过字节流进行传递。
服务器端(C#写的)的数据结构是不能被JAVA客户端识别的。
在服务器端C#将数据结构转换成字符串,然后JAVA端通过输入流获取socket的字节码。
如:
Socket socket=new Socket("127.0.0.1",4700);
        //向本机的4700端口发出客户请求
        BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
        //由系统标准输入设备构造BufferedReader对象
        PrintWriter os=new PrintWriter(socket.getOutputStream());
        //由Socket对象得到输出流,并构造PrintWriter对象
        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //由Socket对象得到输入流,并构造相应的BufferedReader对象
        String readline;
        readline=sin.readLine(); //从系统标准输入读入一字符串
        while(!readline.equals("bye")){
        //若从标准输入读入的字符串为 "bye"则停止循环
          os.println(readline);
          //将从系统标准输入读入的字符串输出到Server
          os.flush();
          //刷新输出流,使Server马上收到该字符串
          System.out.println("Client:"+readline);
          //在系统标准输出上打印读入的字符串
          System.out.println("Server:"+is.readLine());
          //从Server读入一字符串,并打印到标准输出上
          readline=sin.readLine(); //从系统标准输入读入一字符串
        } //继续循环
        os.close(); //关闭Socket输出流
        is.close(); //关闭Socket输入流
        socket.close(); //关闭Socket


JAVA只能获取服务器C#端返回的字节流,然后通过字符串转换成JAVA对象。
对象数据格式转换字符串的方法,可以参照Json格式。也可以在服务器C#端将数据格式转换成XML格式的字符串。JAVA客户端调用后将XML格式的字符串解析成JAVA对象。

zhangfei2007cumt 2012-03-01
  • 打赏
  • 举报
回复
allan0527帮忙看看谢谢
zhangfei2007cumt 2012-02-29
  • 打赏
  • 举报
回复
TCP/IP

服务端数据报结构如下:
struct PacketHeader
{
/// 标志位
short PacketFlag;

//Packet Length
/// 消息包长度(消息包头)
short Length;
//Packet ID
union{
/// 消息ID
int PacketID;//为了方便和别的程序通讯,消息id还是采用枚举定义,在编译期确定
/// 类型(0~9系统预留)
int MsgType;
};
//CheckSum
/// 序列号
int SerialNumber;
//Client or DispatcherID (special use)
union{
/// DispatcherID (special use)
int DispatcherID;
struct {
short FrontEndID;
short ClientID;//On FrontEnd
};
};

PacketHeader()
:PacketFlag(PacketFlag_Normal)
,Length(sizeof(PacketHeader))
,PacketID(0)
,SerialNumber(0)
,DispatcherID(0)
{

}
public:
/// 消息包头的长度
static const int MsgHeaderLength = 16;//16
/// 处理 Msg 所需的最小长度
static const int MsgMustInfoLength = 4;//(ushort + ushort)
/// 最大Msg长度(包括消息包头)
static const int Max_Msg_Size = 32000;//<32K
/// 最小压缩长度
static const int Min_Compress_Size = 100;
/// 分割消息包的大小
static const int SubPacketLength = 1024;//分割消息包的大小


/// 添加标志位
void AddFlag(enumMsgFlag flag) {PacketFlag |= flag;}
/// 获得消息类型
int GetType(){return this->PacketID; }
/// 获得消息包长度
ushort GetLength(){return this->Length; }
};


/// 二进制消息包
struct NGA_CoreLib_Export Msg : public PacketHeader
{
/// 将Msg转换为Packet
/**
使用 TypedTLSMemory 保证线程安全
*/
static Packet* ToPacket(Msg*);//线程安全
/// 将Msg转换为Packet
/**
使用 TypedTLSMemory 保证线程安全
*/
Packet* ToPacket();//线程安全



};

struct SSLMSGSendPublicKey:public Msg
{
SSLMSGSendPublicKey()
{
this->PacketID = MSG_SSLSendPublicKey;
this->Length = sizeof(*this);
int keylen = sizeof(KeyData);
EncryptFlag = PacketFlag_Compress_Need_Checksum;
for(int i=0;i<keylen;i++){
BYTE temp = BYTE(rand()%256);
KeyData[i] = temp;

}
}
uint32 EncryptFlag;
BYTE KeyData[128];
};

msg = buf[]


msg = msg.id
allan0527 2012-02-29
  • 打赏
  • 举报
回复
数据包?
通讯协议?UDP/TCP?HTTP?

50,541

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧