java socket传送一个结构体给用C++编写的服务器解析的问题

另一端是Java写客户端程序,两者之间需要通信。c++/c接收和发送的都是结构体,而Java是直接发送的字节流或者byte 数组。

解决方法:c++/c socket 在发送结构体的时候其实发送的也是字节流。因为结构体本身也是内存中的一块连续数据。问题就变成了如何把结构体手动转成字节的问题了采用类似的报头:
// packet head
typedef struct tagPacketHead{
long PacketID;
long PacketLen;}
PacketHead;此时套接口的读写方式为先读报头,在报头中取出数据负载的长度,然后再读相应字节的数据。

包头后面跟上包体,其中包体的长度,就是上面结构体中的PacketLen,Clinet首先接受包头,因为包头是两边约定好的,所以可以直接Receive一个定长的消息,也就是这个包头的长度的消息,从包头中取得包体的长度后,就可以再次Receive一个包体长度的消息了。那么Java中如何发送一个结构体呢?下面是解决方法:

使用C/S模式,Client为VC6开发,Server为Java,通过Socket通信。
package org.charry.org;
import java.net.*;
/**
*
* 字节转换,参考网络文章
*/
class Packet {
private byte[] buf = null;
/**
* 将int转为低字节在前,高字节在后的byte数组
*/
private static byte[] toLH(int n) {
byte[] b = new byte[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;
}
/**
* 将float转为低字节在前,高字节在后的byte数组
*/
private static byte[] toLH(float f) {
return toLH(Float.floatToRawIntBits(f));
}
/**
* 构造并转换
*/
public Packet(int packetID, int packetLen, String packetBody) {
byte[] temp = null;
buf = new byte[packetBody.getBytes().length + 8];
temp = toLH(packetID);
System.arraycopy(temp, 0, buf, 0, temp.length);
temp = toLH(packetLen);
System.arraycopy(temp, 0, buf, 4, temp.length);
System.arraycopy(packetBody.getBytes(), 0, buf, 8, packetBody.length());
}
/**
* 返回要发送的数组
*/
public byte[] getBuf() {
return buf;
}
/**
* 发送测试
*/
public static void main(String[] args) {
try {
String tmp = “test string!”;
Socket sock = new Socket(”127.0.0.1″, 8888);
sock.getOutputStream().write(
new Packet(123, tmp.length(), tmp).getBuf());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
时间: 2024-10-02 03:04:36

java socket传送一个结构体给用C++编写的服务器解析的问题的相关文章

socket编程——sockaddr_in结构体操作

sockaddr结构体 sockaddr的缺陷: struct sockaddr 是一个通用地址结构,这是为了统一地址结构的表示方法,统一接口函数,使不同的地址结构可以被bind() , connect() 等函数调用:sa_data把目标地址和端口信息混在一起了 struct sockaddr {       unsigned short sa_family; char sa_data[14];                   };  sa_family是通信类型,最常用的值是 "AF_I

计算一个结构体student_type的变量

for(i=0;i<SIZE;i++)    scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age, stud[i].addr):    save():    printf("**********************************\n"):    printf("这是刚才写到文件里的内容\n"):    output():    return 0;   

通过一个函数,操作一个结构体,实现对应函数功能

指针结构体一直是我的盲点,所以今天有必要整“清理门户”.此种通过一个函数操作一个结构体,实现对应函数功能,用法十分巧妙,使用得当可以使得代码可移植性和易懂性大大的增加,有人说过“代码注释的最高境界是程序的自述,而不是双斜杠然后后面跟着中英文的注释”.哈哈,说远了,下面开始进入今天的加油站,补充体力了. 1 // 头文件 2 #include <stdio.h> 3 4 // 函数声明 5 typedef struct _halDeviceFuncs_t 6 { 7 void (*pfnInit

【C++】字节对齐,也就是一个结构体的实际大小

字节对齐是面试笔试经常考到的一个知识点 计算一个结构体大小只需要进行如下几个步骤即可. 1.确认结构体中所有成员的长度大小 可以引用此表. char short int long float double long long long double Win-32 长度 1 2 4 4 4 8 8 8 模数 1 2 4 4 4 8 8 8 Linux-32 长度 1 2 4 4 4 8 8 12 模数 1 2 4 4 4 4 4 4 Linux-64 长度 1 2 4 8 4 8 8 16 2.确

C语言-对一个结构体中的字段进行排序

这是帮别人做的一个题目,好久没有接触过C语言了.有点发怵,只是似乎找回点当时学C语言,做课程设计的感觉. 题目:定义一个数组(学生结构体数组),里面包括学号.姓名.身份证和三科学生成绩.要求写一个函数,依据学生不论什么一个字段(如学号.姓名.身份证),进行排序. 源代码: //// stu.cpp : Defines the entry point for the console application. //// // #include "stdafx.h" //----------

IOS开发把一个结构体放到数组中

oc中的可变数组NSMutableArray里面只能存放object,对于结构体类型,必须进行转换才能放入可变数组 NSMutableArray *coordinateArray = [NSMutableArray array]; CLLocationCoordinate2D coor; coor.latitude = item.latitude; coor.longitude = item.longitude; NSValue *value = [NSValue value:&coor wit

3. file、inode结构体及chardevs数组等相关知识解析

https://blog.csdn.net/zqixiao_09/article/details/50850004 下图描述了Linux中虚拟文件系统,一般的设备文件与设备驱动程序间的函数调用关系 上图展现了一个应用程序调用字符设备驱动的过程,在设备驱动程序的设计中,一般而言,会关系file和inode这两个结构体. 用户空间使用open()函数打开一个字符设备fd = open("/dev/hello", o_READ);这一函数会调用两个数据结构struct inode{}&

java socket传送和接受byte[]

数据发送端(客户端):   //创建一个Socket对象,连接IP地址为192.168.101.56的服务器的9002端口               Socket s = new Socket("192.168.101.56",9002); byte[] content=new byte[100];    content[0]=(byte) 0xE2;     content[1]=(byte) 0x5C; String fix="HHCYFI"; byte[]

socket协议-根据结构体写包,接收

init: #include "lrs.h" #define PROTOVER 351enum RET_ERROR{ SUCCESS=0, ERROR, WHILE};enum errorCode{ ERROR_NULL=0, ERROR_NO_SIZE, ERROR_BUFFER_POINT, ERROR_POINT, ERROR_ALLOC_MEM, ERROR_WRITE_OVERFLOW, ERROR_READ_OVERFLOW, ERROR_NO_MOVE, ERROR_AD