java 和C++ Socket程序发送结构体
来源:互联网 发布:淘宝直播浮现规则 编辑:程序博客网 时间:2024/05/21 10:00
主要技术问题:windows,linux等系统采用LITTLE_ENDIAN字节序,而java自身采用BIG_ENGIAN字节序,BIG_ENGIAN是指低地址存放最高有效字节(MSB),而LITTLE_ENDIAN则是低地址存放最低有效字节。Java程序写的客户程序端同c++的服务端程序交互时结构体的某些数据类型需要转换字节序。本文解决方法,java客户端程序发送数据时做相应的转换字节序,等收到数据时再做一次字节序的转换。
现在的网络程序多数采用可靠交付的TCP协议,其采用字节流的传输方式,c++程序中用结构体来模拟报头以此界定每次发送的报文。所以网络中整个字节流的格式:报头+数据负载+报头+数据负载……
本文基于c++写服务端和java写客户端应用场景描述。服务端程序收到客户端发送的报文后将原报文做一个回射。
采用报头:
Struct Header{
Intcmd; //标示报文用途
Intlength; //数据负载长度
Intpara1; //服务端处理完结果
Int para2; //服务端处理完结果
Int para3; //服务端处理完结果
}; 此时套接口的读写方式为先读报头,在报头中取出数据负载的长度,然后再读相应字节的数据。
Java客户端代码:
报头类:
publicclassMsgHeader {
privateintcmd;
privateintlength;
privateintpara1;
privateintpara2;
publicint getCmd() {
returncmd;
}
publicvoid setCmd(int cmd) {
this.cmd = cmd;
}
publicint getLength() {
returnlength;
}
publicvoid setLength(int length) {
this.length = length;
}
publicint getPara1() {
returnpara1;
}
publicvoid setPara1(int para1) {
this.para1 = para1;
}
publicint getPara2() {
returnpara2;
}
publicvoid setPara2(int para2) {
this.para2 = para2;
}
publicint getPara3() {
returnpara3;
}
publicvoid setPara3(int para3) {
this.para3 = para3;
}
privateintpara3;
public MsgHeader()
{
this.cmd = 0;
this.length = 0;
this.para1 = 0;
this.para2 = 0;
this.para3 = 0;
}
public MsgHeader(int cmd,int length,int para1,int para2,int para3){
this.cmd=cmd;
this.length= length;
this.para1 = para1;
this.para2 = para2;
this.para3 = para3;
}
}
公共操作类:
publicclassCommon {
//字节序转换
publicstaticbyte[] toLH(int n) {
byte[] b =newbyte[4];
b[0]= (byte)(n & 0xff);
b[1]= (byte)(n >> 8 & 0xff);
b[2]= (byte)(n >> 16 & 0xff);
b[3]= (byte)(n >> 24 & 0xff);
return b;
}
//btye数组转换为int型
publicstaticint bytes2Integer(byte[] byteVal) {
int result = 0;
for (int i = 0; i < byteVal.length; i++) {
int tmpVal = (byteVal[i]<< (8 * (3 - i)));
switch (i) {
case 0:
tmpVal= tmpVal & 0xFF000000;
break;
case 1:
tmpVal= tmpVal & 0x00FF0000;
break;
case 2:
tmpVal= tmpVal & 0x0000FF00;
break;
case 3:
tmpVal= tmpVal & 0x000000FF;
break;
}
result= result | tmpVal;
}
return result;
}
}
协议类:
publicclassProtocol {
publicstaticfinalintPORTAL_DBC_INSTALLSYSTEM= 0x05000030;
publicstaticfinalintPORTAL_DBC_INSTALLSYSTEM_ACK= 0x05000031;
/*
* add all protocol
*
*
*
*/
}
数据收发类:
publicclassDBCAgent {
private Socketsocket =null;
privatebyte[]buffer;
public DBCAgent() {
try {
this.socket =new Socket("192.168.9.64",8886);
}catch(UnknownHostException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
//收数据
publicvoid recvData()throws IOException {
byte[] recvHead =newbyte[4];
int cForm;
intcmd, length,para1,para2, para3;
// readcmd转换字节序
socket.getInputStream().read(recvHead,0, 4);
cForm= Common.bytes2Integer(recvHead);
cmd= Common.bytes2Integer(Common.toLH(cForm));
// read length转换字节序
socket.getInputStream().read(recvHead,0, 4);
cForm= Common.bytes2Integer(recvHead);
length= Common.bytes2Integer(Common.toLH(cForm));
// read para1转换字节序
socket.getInputStream().read(recvHead,0, 4);
cForm= Common.bytes2Integer(recvHead);
para1= Common.bytes2Integer(Common.toLH(cForm));
// read para2转换字节序
socket.getInputStream().read(recvHead,0, 4);
cForm= Common.bytes2Integer(recvHead);
para2= Common.bytes2Integer(Common.toLH(cForm));
// read para3转换字节序
socket.getInputStream().read(recvHead,0, 4);
cForm= Common.bytes2Integer(recvHead);
para3= Common.bytes2Integer(Common.toLH(cForm));
byte[] recvData =newbyte[length];
// read data
socket.getInputStream().read(recvData,0, length);
StringDataStr = newString(recvData);
System.out.println(DataStr);
}
发数据类:
publicboolean sendData(String data) {
byte[] temp =null;
MsgHeaderheader = newMsgHeader();
header.setLength(data.length());
this.buffer =newbyte[data.length() + 20];
// addcmd转换字节序
temp= Common.toLH(Protocol.PORTAL_DBC_INSTALLSYSTEM);
System.arraycopy(temp,0,buffer,0, 4);
// addlength转换字节序
temp= Common.toLH(header.getLength());
System.arraycopy(temp,0,buffer,4, 4);
// add para1转换字节序
temp= Common.toLH(header.getPara1());
System.arraycopy(temp,0,buffer,8, 4);
// add para2转换字节序
temp= Common.toLH(header.getPara2());
System.arraycopy(temp,0,buffer,12, 4);
// add para3转换字节序
temp= Common.toLH(header.getPara3());
System.arraycopy(temp,0,buffer,16, 4);
System.arraycopy(data.getBytes(),0,buffer,20, data.length());
try {
socket.getOutputStream().write(this.buffer);
}catch(IOException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
returntrue;
}
}
测试类:
publicclassTest {
/**
* @param args
* @throws IOException
*/
publicstaticvoid main(String[] args)throws IOException {
//TODO Auto-generated method stub
DBCAgentdbcAgent = newDBCAgent();
//发送数据
dbcAgent.sendData("Helloaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
//接收数据
dbcAgent.recvData();
try {
Thread.sleep(10000);
}catch(InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}- java 和C++ Socket程序发送结构体
- JAVA和C++通过socket发送和接收结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- c/c++通过socket发送结构体
- C语言udp socket发送结构体
- python的socket发送C结构体
- Socket发送和接收变长结构体
- socket发送结构体
- c/c++通过socket发送结构体以及类对象
- C语言socket通信发送结构体的问题
- C++ socket发送结构体
- socket发送结构体 小结
- 通过socket发送结构体
- shell 知识点补充(2)-重定向/ ; , &&, ||/管线命令/grep/sort/ uniq/wc/tee/tr/col/join/paste/expand/split/-
- 教育部:军事国防等专业可按男女比例招生-高考招生-性别-歧视
- java程序
- HDU 1251
- 一位码农的人生自述(四十五)------表白
- java 和C++ Socket程序发送结构体
- 电脑围棋中的人工智能技术
- <每日一句英语> 2012-10-18
- 四川调整村卫生室一般诊疗费标准按5元收取-四川-村卫生室-收费
- 关于yuv 格式-Semi Planar和Planar
- 查数
- inet_addr()、inet_network()、inet_aton()的区别
- Java读取Properties文件的六种方法
- 幸运数组/连续子数组被k整除