问题: 服务器是用java写的,客户端是用actionscript(使用amf3)写的,但是服务器端只发送了两次信息,
客户端却接收到三次数据,服务器端也是同样的问题,接收到客户端的三次数据,但是客户端也只发了
两次信息。
由于socket传输数据时是按固定的大小传送字节数据的,但是在flash客户端读取的
时候是靠一个readObject方法,也就是每次flash客户端读取的时候都是按一个完整
的对象来读取每一次的socket的,但是在服务器端有可能socket将一个完整的序列化
对象给分开来传输,这也就是我们遇到的问题,为什么有时候能够正常接收到数据,而
有时候却只是接收到数据却无法读取的原因。解决的办法就是在客户端读取数据之前,
先将数据存放在一个容器里面(这个需要大家自己去想了),等flash客户端接收到所有
的数据之后,再从该容器中将该对象读取出来,这样问题就解决了。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.ASObject;
import flex.messaging.io.amf.Amf3Input;
import flex.messaging.io.amf.Amf3Output;
public class LgServerThread extends Thread
{
SerializationContext seri=new SerializationContext();//序列化输入输出流
Amf3Output amfout=new Amf3Output(seri);//格式化输出流
Amf3Input amfin=new Amf3Input(seri);//格式化输入流
ByteArrayOutputStream baos=new ByteArrayOutputStream();//创建二进制输入流
ByteArrayInputStream bais=null;//创建二进制输入流
DataOutputStream dos=new DataOutputStream(baos);//转化二进制流为数据输出流
DataInputStream dis=null;//创建输入流
Socket socket;
InputStreamReader isr;//将输入流信息由字符型转换为字节型
BufferedReader br;//将输入流信息放入缓存
OutputStreamWriter osw = null;//使用amf3格式将写入流中的数据编码成字节
BufferedWriter bw;//用来封装OutputStreamWriter,以提高效率
Boolean eventFlag=true;
//LgServerThread的构造函数
public LgServerThread(Socket socket)
{
this.socket=socket;
}
public void Init()
{
try {
amfin.setInputStream(socket.getInputStream());
amfout.setOutputStream(dos);
isr=new InputStreamReader(socket.getInputStream());
br=new BufferedReader(isr);//将流中的数据放入缓存
osw=new OutputStreamWriter(socket.getOutputStream());//将字符流转化为字节流
bw=new BufferedWriter(osw);//封装osw对象,提高写入的效率
} catch (IOException e) {
e.printStackTrace();
}
}
public void run()
{
HashMap map;
try {
Init();
while(eventFlag)
{
ASObject message = ReceiveMsg();
if(message!=null)
{
String event=(String)message.get("event");
if(event!=null)
{
if(event.equals("cookie"))
{
map=new HashMap();
map.put("event", "checkMsg");
map.put("checkRuesult", "true");
map.put("session","thisissession");
amfout.writeObject(map);//实际上是将map对象写入到dataoutstream流中
dos.flush();//清空缓存
map=null;
byte[] messageBytes1=baos.toByteArray();//amf3数据
socket.getOutputStream().write(messageBytes1);//向流中写入二进制数据
socket.getOutputStream().flush();
}
else if(event.equals("requestRoleInit"))
{
if(message.get("requestMsg").equals("roleInit"))
{
map=new HashMap();
map.put("event", "roleInit");
map.put("session", "thisissession");
map.put("roleName","estone");
map.put("sceneInfo", "map.gif");
map.put("roleLocation", "100/100");
amfout.writeObject(map);//实际上是将map对象写入到 dataoutstream流中
dos.flush();//清空缓存
map=null;
byte[] messageBytes2=baos.toByteArray();//amf3数据
socket.getOutputStream().write(messageBytes2);//向流中写入二进制数据
socket.getOutputStream().flush();
}
}
}
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
public ASObject ReceiveMsg()
{
ASObject object=null;
while(true)
{
try {
object =(ASObject) amfin.readObject();
System.out.println();
System.out.println("<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>");
System.out.println(object);
System.out.println("<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>");
System.out.println();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return object;
}
}
public void SendMsg(byte[] message)
{
}
}
package cls {
import flash.net.Socket;
import flash.display.Sprite;
import flash.events.*;
import flash.text.TextField;
public class SocketLink extends Sprite
{
private var socket:Socket;
private var obj:Object;
private var sessions:String;
private var infoTxt:TextField;
private var requestObj:Object;
public function SocketLink(url:String, port:int):void
{
socket = new Socket();
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
socket.addEventListener(Event.CLOSE, closeHandler); socket.connect(url, port);
}
public function init():void
{
var temp = this.parent; infoTxt = temp.infoTxt;
} //接收服务器数据
private function socketDataHandler(event:ProgressEvent):void
{
infoTxt.appendText("接收数据/n");
obj = new Object();
obj = socket.readObject();
for (var k in obj)
{
trace(k + ":" + obj[k]);
}
trace("----------------------------------");
recievedData();
} //测试接收到的数据
private function recievedData()
{
switch(obj.event)
{
case "checkMsg":
infoTxt.appendText("第一次接收到的数据为" + obj.checkRuesult + "," + obj.session + "/n");
if (obj.checkRuesult)
{
infoTxt.appendText("登陆成功" + "/n"); sessions = obj.session; RequestFun();
}
else
{
infoTxt.appendText("登陆失败" + "/n");
}
break;
case "roleInit":
infoTxt.appendText("第二次接收到的数据为" + obj.session + "," + obj.roleName + "," + obj.sceneInfo + "," + obj.roleLocation + "/n");
infoTxt.appendText("当前的session为:" + obj.session + ",将人物" + obj.roleName + "移动到地图" + obj.sceneInfo +"的" + obj.roleLocation + "的位置" + "/n");
break;
}
}
private function RequestFun():void
{
requestObj = new Object();
requestObj = { event:"requestRoleInit", session:sessions, userName:"zhangfan", requestMsg:"roleInit" };
socket.writeObject(requestObj); socket.flush();
} //Socket已连接,发送数据
private function connectHandler(event:Event):void
{
infoTxt.appendText("连接成功" + "/n");
requestObj = new Object(); requestObj = { event:"cookie", cookie:"cookieMsg" };
socket.writeObject(requestObj); socket.flush();
} //错误处理
private function ioErrorHandler(event:IOErrorEvent):void
{
infoTxt.appendText("ioErrorHandler信息: " + event + "/n");
} //安全问题处理
private function securityErrorHandler(event:SecurityErrorEvent):void
{
infoTxt.appendText("securityErrorHandler信息: " + event + "/n");
} //关闭Socket连接
private function closeHandler(event:Event):void
{
infoTxt.appendText("连接关闭" + "/n");
}
}
}