转自: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
原文:http://www.cnblogs.com/regalys168/p/3614687.html