首页 > 其他 > 详细

关于socket使用Amf直接进行对象传输的

时间:2014-03-21 03:47:36      阅读:551      评论:0      收藏:0      [点我收藏+]

转自:topic.csdn.net/u/20080924/11/1b3ddc7c-4080-4b6c-b491-5cbf1fa7f631.html

原文如下:

 

问题如下: 服务器是用java写的,客户端是用actionscript(使用amf3)写的,但是服务器端只发送了两次信息, 客户端却接收到三次数据,服务器端也是同样的问题,接收到客户端的三次数据,但是客户端也只发了 两次信息。

java服务器端的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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)
    {
         
   

  客户端代码ActionScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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");
        }
    }
}

  

该文的评论如下:

A:我也遇到了相似的问题,客户端的一条数据被分成了两条发送给服务端

B:好像听别人说起过,sorket通信时,如果传送字符串较长的话,会自动分开后传过去。

楼主:关于这个问题现在我们已经解决了,但是由于一些原因,现在还不能将该问题的源码 放在论坛上面,但是我在这里讲解一下这个问题的一些思路: 由于socket传输数据时是按固定的大小传送字节数据的,但是在flash客户端读取的 时候是靠一个readObject方法,也就是每次flash客户端读取的时候都是按一个完整 的对象来读取每一次的socket的,但是在服务器端有可能socket将一个完整的序列化 对象给分开来传输,这也就是我们遇到的问题,为什么有时候能够正常接收到数据,而 有时候却只是接收到数据却无法读取的原因。解决的办法就是在客户端读取数据之前, 先将数据存放在一个容器里面(这个需要大家自己去想了),等flash客户端接收到所有 的数据之后,再从该容器中将该对象读取出来,这样问题就解决了。 我们现在用的就是这个方法,经过无数的测试后,这个方法是可行的,直到现在我们的 服务器现在还运行的好好的。 这算是对这个问题的一个结贴吧,希望对大家有所帮助。  

关于socket使用Amf直接进行对象传输的,布布扣,bubuko.com

关于socket使用Amf直接进行对象传输的

原文:http://www.cnblogs.com/regalys168/p/3614687.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!