经过大概2周的时间,做完了1个JAVA做服务器FLASH做客户端的交互例子。期间碰到些麻烦事,总结下做个记录。
1.安全域问题,当服务器在本地启动的时候,如果没有进行对应配置直接让FLASH访问服务器的对应端口会出现安全错误。解决方法很简单,在服务端简历843线程(FLASH访问SOCKET会自动去该线程申请域策略文件),当发现该线程有FLASH访问的时候,服务端发送回一个域策略安全的XML即可。
2.因为JAVA服务端是多线程的,因此涉及到线程池的使用,这里用了JDK1.5自带的,很方便。使用线程池可以减少内存的损耗并且增加并发性。
3.粘包问题,当服务端几乎在同一时间向一个客户端发送多条SOCKET的时候,有时候会出现客户端只收到1条完整的,其他的被抛弃掉了。解决办法,服务端发送SOCKET的同时先检测要发送的东西的长度,生成一个4位的长度头加在信息前面。当客户端读取到得时候先根据长度头去读长度,然后再读对应的长度的消息。当读完对应长度后如果还有消息则就可以判定是粘包了,这时继续重新读长度头然后再读信息即可。
4.中文问题。
写入的时候用:
var message:ByteArray=new ByteArray();
message.writeUTFBytes(txt +"/r/n");
//写入数据,writeUTFBytes方法,以utf-8格式传数据避免中文乱码
socket.writeBytes(message);
//写入Socket的缓冲区
socket.flush();
读出的时候用:
socket.readBytes(bytes, bytes.length , msgLen);
这样一读一写基本能保证中文正常。(之前发现过当写入的时候是UTF-8,读出必须用socket.readMultiByte(socket.bytesAvailable,"utf-16");来读才能读出中文,不然就是乱码的奇怪问题)
5.当采用3的方法发送信息的时候,粘包问题解决的手段需要注意删除多余的结束字符,即用lsStr = lsStr.slice(0,lsStr.length - 2);这样的形式来删除掉最后的"/n"。同时要注意因为中文在FLASH和JAVA里1位都只算1长度,因此在服务器端算长度头的时候要针对中文进行操作。
private int getStrLength(String _str) {
int len = 0;
for (int j = 0; j < _str.length(); j++) {
int code = _str.charAt(j);
if ( code < 0 || code > 255) {
len += 2;
} else {
len += 1;
}
}
return len;
}
JAVA的处理方式。