我们使用AS3事件:ProcessEvent.SOCKET_DATA来侦听套接字数据。 所以这是我的套接字数据句柄的AS3代码。
private function packetHandler( e:ProgressEvent ):void
{
while( m_socket.bytesAvailable && m_socket.bytesAvailable >= pLen )
{
//pLen means the packet length
//pLen init is zero
if( pLen == 0 )
{
//PACKET_LEN stands for the solid length of one packet
//PACKET_LEN = HEAD_LEN + 4
//the 4 means an unsigned int which means the packet content length
if( m_socket.bytesAvailable > PACKET_LEN )
{
m_socket.readBytes( headByteBuffer, 0, HEAD_LEN );
headByteBuffer.clear();
pLen = m_socket.readUnsignedInt() + 4;
}
else
{
break;
}
}
//recieved a whole packet now handle it
else
{
var newPacket:ByteArray = new ByteArray();
newPacket.endian = Endian.LITTLE_ENDIAN;
m_socket.readBytes( newPacket, 0, pLen );
parasMsg( newPacket, pLen-4 );
pLen = 0;
}
}
}
可以在此图片中描述整个数据包:
我的问题是:当Flash中收到一个不完整的数据包并触发了句柄。 但数据包的左侧部分永远不会触发句柄,看起来数据包的左侧部分已丢失!!!
我使用了一个捕获工具,发现tcp数据包没问题,但为什么左边部分没有再次触发事件?
您可以在下面获得更多调试信息。谢谢!
这是我的日志:
==> sendPacket:{“rangeID”:“1”,“uid”:“145962”,“serviceType”:“copyscene”,“cmd”:“CopySceneMoveAsk”,“pathPoint”:[{“col “:7,” 行 “:6},{” 栏 “:7,” 行 “:5},{” 栏 “:7,” 行 “:4},{” 栏 “:7,” 行“: 3},{ “栏”:6, “行”:3}], “SN”: “79”, “smallPathPoint”:[[22,19],[22,18],[22,17],[ 22,16],[22,15],[22,14],[22,13],[21,13],[21,12],[21,11],[20,11],[20, 10]]},bytesLoaded = 463
ProgressEvent已触发!0套接字byteava = 373 evt已加载:373 evt total:0 evt:[ProgressEvent type =“socketData”bubbles = false cancelable = false eventPhase = 2 bytesLoaded = 373 bytesTotal = 0]
从套接字中查找数据包,pLen = 288 socket byteava = 276
ProgressEvent已触发!288套接字byteava = 441 evt已加载:165 evt total:0 evt:[ProgressEvent type =“socketData”bubbles = false cancelable = false eventPhase = 2 bytesLoaded = 165 bytesTotal = 0]
开始读取要缓冲的数据包,pLen = 288 socket byteava = 441
整个数据包内容:将数据包重命名为缓冲区,pLen = 288 socket byteava = 153
服务器数据包内容字节缓冲区ava:288 len:288 pos:0
服务器Paras数据:数据len:284数据内容:{“cmd”:“CopySceneMoveNotify”,“gtcmd”:“108”,“layer”:“1”,“pathPoint”:[{“col”:7 , “行”:6},{ “栏”:7, “行”:5},{ “栏”:7, “行”:4},{ “栏”:7, “行”:3}, { “栏”:6, “行”:3}], “smallPathPoint”:[[22,19],[22,18],[22,17],[22,16],[22,15], [22,14],[22,13],[21,13],[21,12],[21,11],[20,11],[20,10] HTTP / 1.1 200
_[20,10]HTTP/1.1 200_
这就是出错了!!带有另一个数据包标题的不完整数据包cat。
以下是TCP连接的捕获:
希望你能投票,以便我可以把这个问题的照片放在上面!
我的英语不是很好,希望你能明白我的意思。 谢谢!
答案 0 :(得分:0)
Socket的事件flash.events.ProgressEvent.SOCKET_DATA将在您收到数据时触发,您可以获取接收的字节(检查.bytesAvailable)。当msg被拆分为多个包时,您将收到每个数据包的事件。 在你的情况下,当检查m_socket.bytesAvailable> = pLen时,pLen可能有错误的值。
我假设您在消息的请求中发送msg大小(在这种情况下,您可以检查是否收到了整个消息)。在这种情况下,您必须有一个类成员(ByteArray)作为保存接收字节的缓冲区。当新数据到来时,您必须将新字节复制到此成员,而不是检查是否收到整个消息。如果buffer包含整个msg而不是从中删除msg。 通常,您的事件处理程序必须如下所示:
protected function onSocketData( pEvt: Event ): void
{
try
{
if ( 0 < pEvt.target.bytesAvailable )
{
var byteStream: ByteArray = new ByteArray();
pEvt.target.readBytes( byteStream, 0, Socket( pEvt.target ).bytesAvailable );
// Append readed data to your buffer
do
{
//Check if you have enough bytes to read whole msg and execute it
//do..while because maybe it can be more than one msg in buffer
}
while ( null != msgContent );
}
}
catch ( exc )
{
}
}
答案 1 :(得分:0)
问题应该由数据包的实体标题引起。
以下是数据包的93字节实体标题。
private static const HTTP_RESPONSE_CONTENT : String = "HTTP/1.1 200 OK \r\n"
+ "Connection: keep-alive \r\n"
+ "Content-Length: 280 \r\n"
+ "Content-Type: text/html \r\n\r\n";
此标头将位于每个数据包的标头中,AS3可将其处理为http
,并可能使用Content-Length: 280
切断流量。所以280字节的左边部分永远不会触发SOCKET_DATA事件。
当我删除此标题时,现在就可以了。