如题, 我要和C语言程序作socket通讯,但C语言程序中的socket发送接收都用了结构体,而java中没有结构体的概念,我该怎么作? 为每一个C结构体写一个对应的类? 那我的类怎么接收它的结构体呢?谁给举个例子呀多谢了, 在线等待..
解决方案 »
- java引入图片,在项目中可以运行,打包后无法正常运行
- ArrayList 不能转成 Collection
- 我的这段代码sum值在第一次计算时不出错,为什么重复循环的时候sum值出错?
- 谁能把一个JDialog的大小设置成(50,300),100分相送!
- 能否帮我实现这个程序中计算出盘子移动的次数呀
- 子类到底继承什么?大侠请进
- 大家不要见笑,问一个关于垃圾回收的问题?
- 关于LOOKANDFEEL~
- 如何在java Applet中使用File Chooser?
- 有关于链表实现搜索数据的问题
- 高分求求一socket客户端例子..包括"握手",发送请求包.得到server端回馈包,谢谢各位
- 如何解决下中文字体难看的问题????????
通信协议必须明确规范每一个字段的类型、长度、字节顺序等信息,直接发结构体,那么除非两边都使用C语言编程,而且使用同样类型的CPU,使用同样的编译器编译,而且使用同样的编译选项。
但是对方的c程序就是发送一个结构体数据过来,我现在的问题就是怎么接收它呢?
我把数据全部接收过来后,然后取前多少字节作为一个东西,再取从某个位置到某个位置的若干字节作为另外一个东西,但是不同的机器和操作系统上相同数据类型也未必占用相同的字节,我这样作也会存在问题吧? 我该怎么作呢?
char UserName[20];
int UserId;
};
struct Employee {
UserInfo user;
float salary;
};
当然也可以定义为struct Employee {
char name[20];
int id;
float salary;
};
java client 测试源码(为说明问题,假设struct字节对齐,sizeof(Employee)=28)import java.net.*;/**
* 与C语言通信(java做Client,c/c++做Server,传送一个结构)
* @author kingfish
* @version 1.0
*/
class Employee {
private byte[] buf = new byte[28]; //为说明问题,定死大小,事件中可以灵活处理 /**
* 将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 Employee(String name, int id, float salary) {
byte[] temp = name.getBytes();
System.arraycopy(temp, 0, buf, 0, temp.length); temp = toLH(id);
System.arraycopy(temp, 0, buf, 20, temp.length); temp = toLH(salary);
System.arraycopy(temp, 0, buf, 24, temp.length);
} /**
* 返回要发送的数组
*/
public byte[] getBuf() {
return buf;
} /**
* 发送测试
*/
public static void main(String[] args) {
try {
Socket sock = new Socket("127.0.0.1", 8888);
sock.getOutputStream().write(new Employee("kingfish", 123456789, 8888.99f).
getBuf());
sock.close();
}
catch (Exception e) {
e.printStackTrace();
}} //end---------------------------------------------------------------------------当然,也可以利用writeInt,writeFloat方法发送,但字节顺序需要改为低在前。
这个问题稍后在讨论。
如有任何问题,请指正!kingfish
2005.3.29
import java.net.*;
import java.io.*;/**
* 与C语言通信(java做Client,c/c++做Server,传送一个结构)
* @author kingfish
* @version 1.0
*/
public class Employee2 {
private String name;
private int id;
private float salary; /**
* 将int转为低字节在前,高字节在后的int
*/
private static int toLH(int in) {
int out = 0;
out = (in & 0xff) << 24;
out |= (in & 0xff00) << 8;
out |= (in & 0xff0000) >> 8;
out |= (in & 0xff000000) >> 24;
return out;
} /**
* 将float转为低字节在前,高字节在后的int
*/
private static int toLH(float f) {
return toLH(Float.floatToRawIntBits(f));
} /**
* 构造并转换
*/
public Employee2(String name, int id, float salary) {
this.name = name;
this.id = id;
this.salary = salary;
} /**
* 取得名字,定长byte数组
*/
public byte[] getName() {
byte[] b = new byte[20];
System.arraycopy(name.getBytes(), 0, b, 0, name.getBytes().length);
return b;
} /**
* 取得编号(低字节在前)
*/
public int getId() {
return toLH(id);
} /**
* 取得工资(低字节在前)
*/
public int getSalary() {
return toLH(salary);
} /**
* 发送测试
*/
public static void main(String[] args) {
try {
Employee2 p = new Employee2("kingfish", 123456789, 8888.99f); Socket sock = new Socket("127.0.0.1", 8888);
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
dos.write(p.getName());
dos.writeInt(p.getId());
dos.writeInt(p.getSalary());
sock.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
} //end-----------------------------------------------------------------------------------------------------如有任何问题,请指正!kingfish
2005.3.30
(1)对于多字节类型,比如int,它那边的CPU是高字节在前还是低字节在前,现在Intel X86系列的CPU用得多,一般是低字节在前。但如果他转换过了,那么可能就是高字节在前。
(2)他编译时是否按俺默认的结构体字对齐还是重新设过pack选项,如果是默认的,那么通常是按照4字节对齐,比如有个char[21]字段,后面跟一个int,那么取出21个字节的字符串之后,应该跳过3个字节取int。当然,如果它设置了pack(1),没有字节对齐,最好。
是啊,所以我的疑问就是这样弄有太多的写死的情况,遇到某些机器和系统就得改程序,显然这样的程序是一个很失败的程序. 真的找不到一个好的解决方法了吗?
(1)实际中使用的可能还是Intel X86系列的CPU多一些,所以基本上可以按照低字节在前统一处理;
(2)如果原来程序的作者不太服责,那么说不定他根本没改过编译器的默认编译选项,就是采用默认的4字节对齐,也可以统一处理。
(3)也说不定你们的结构体里面没有需要填充的区域,比如没有char[M]后面接一个int字段的情况,而M不是4的整数倍,也没有连续奇数个short然后接着一个int的情况。当然,还有一种可能,那就是原来程序的作者还是比较负责的,他已经采用编译选项取消了字对齐,而且采用字节顺序转换函数把所有的多字节字段都转换成了网络传输中通用的高字节在前的顺序,那样就更好了。