前面写了个传输的原型,现在应该写一下消息的编解码
其实消息的编解码很简单,Socket一般用来传输byte[] ,只要把一个Message的JavaBean对像转成码流,再将其从码流转回成原来的对像就可以了,在这里我们有几种实现的方法
1.写一些类型转换的类,比如int to bytes , longToBytes , StringToBytes ..... 再对每个类进行转换就可以了,这样的好处就是速度会比较快,但是代码要写很多,每个类都需要为他写一个定制的转换的encode与decode,其中可能有人要问为什么String还要写一个toBytes的方法呢? 其实是因为我们要将一个JavaBean转成一个码流,我们并不知道String是在这个码流的什么位置,就算知道位置也不能确定他的长度,因为他是个变长的,所以我们会在String.toBytes后再在前面加一段四个字节的Int型的length。
2.通过反射将类转换成码流,这个方法可以做到通用,但是性能上没有保证。
3.直接序列化与反序列化
其中2与3来做的话开始我准备用2,性能也要比序列化快一倍以上,可以在类不断的变的复杂时性能也在成倍的减少,最后竟然还不如序列化了所以2号方法就不再采用直接用序列化的方法。
简单的代码在下面,没有作过多的处理,以后有机会再完善吧,其实这个方法在commons-lang包中也有可以查看他的原码
package demo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Coder {
public static byte[] encode(Object obj) throws IOException {
ByteArrayOutputStream bis = null;
ObjectOutputStream os = null;
try {
bis = new ByteArrayOutputStream(1024);
os = new ObjectOutputStream(bis);
os.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null)
bis.close();
if (os != null)
os.close();
}
return bis.toByteArray();
}
public static Object decode(byte[] src) throws IOException,
ClassNotFoundException {
ObjectInputStream ois = null;
ByteArrayInputStream bos = null;
try {
bos = new ByteArrayInputStream(src);
ois = new ObjectInputStream(bos);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null)
bos.close();
if (ois != null)
ois.close();
}
return ois.readObject();
}
}