8 个解决方案
#1
数据包?
通讯协议?UDP/TCP?HTTP?
通讯协议?UDP/TCP?HTTP?
#2
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
服务端数据报结构如下:
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
#3
allan0527帮忙看看谢谢
#4
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对象。
服务器端(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对象。
#5
首先谢谢你的回答,我也想到用数据流来操作了,但是服务器端现在写好的好像没有数据流相关操作,让我用数据包的方式跟服务器通信。服务器数据包代码如下:
/// <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();
}
}
请问我用数据包的方式要怎样做呢?
/// <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();
}
}
请问我用数据包的方式要怎样做呢?
#6
如果不加包报头直接发数据流过去的话,服务器端解析出来不对。。。
#7
public class Packet这个数据包对象是C#里面定义的,客户端当然无法解析。我的意思是用字符串来表示,如json格式的字符串,如:
"packet{MaxLength:32000;InvalidLength:-1;NeedCompressMinLength:100;NoCryptHeaderLength:4...}"
JAVA客户端系统拿到这个字符串后,通过字符串处理,把它转换成JAVA对象。
"packet{MaxLength:32000;InvalidLength:-1;NeedCompressMinLength:100;NoCryptHeaderLength:4...}"
JAVA客户端系统拿到这个字符串后,通过字符串处理,把它转换成JAVA对象。
#8
呵呵,谢谢指点
#1
数据包?
通讯协议?UDP/TCP?HTTP?
通讯协议?UDP/TCP?HTTP?
#2
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
服务端数据报结构如下:
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
#3
allan0527帮忙看看谢谢
#4
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对象。
服务器端(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对象。
#5
首先谢谢你的回答,我也想到用数据流来操作了,但是服务器端现在写好的好像没有数据流相关操作,让我用数据包的方式跟服务器通信。服务器数据包代码如下:
/// <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();
}
}
请问我用数据包的方式要怎样做呢?
/// <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();
}
}
请问我用数据包的方式要怎样做呢?
#6
如果不加包报头直接发数据流过去的话,服务器端解析出来不对。。。
#7
public class Packet这个数据包对象是C#里面定义的,客户端当然无法解析。我的意思是用字符串来表示,如json格式的字符串,如:
"packet{MaxLength:32000;InvalidLength:-1;NeedCompressMinLength:100;NoCryptHeaderLength:4...}"
JAVA客户端系统拿到这个字符串后,通过字符串处理,把它转换成JAVA对象。
"packet{MaxLength:32000;InvalidLength:-1;NeedCompressMinLength:100;NoCryptHeaderLength:4...}"
JAVA客户端系统拿到这个字符串后,通过字符串处理,把它转换成JAVA对象。
#8
呵呵,谢谢指点