flash 的socket 真不錯,什么事都內部給辦了,換了java,有些麻煩。
網上那些nio的例子簡單到無實際價值。
ByteBuffer totalReceiveBuff = ByteBuffer.allocate(30000);


..



private void newParseSocketData(int remainSize,SelectionKey key) throws IOException
{
if (remainSize == 0)
totalReceiveBuff.clear();
int firstReadSize = remainSize;
while(true)

{
if(key.isReadable())

{
firstReadSize += sc.read(totalReceiveBuff);
break;
}

try
{
Thread.sleep(200);

} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

if (firstReadSize < 8)
{
System.out.println(firstReadSize + "sssss");
return;
}
totalReceiveBuff.flip();

if (totalReceiveBuff.getInt() != 開始標識)
{
return;
}

int msgLength = totalReceiveBuff.getInt();


if (totalReceiveBuff.remaining() < msgLength + 4)
{
int hasReadSize = firstReadSize;
int totalSize = msgLength + 12;
totalReceiveBuff.position(totalReceiveBuff.limit());
totalReceiveBuff.limit(totalReceiveBuff.capacity());

while (true)
{
int currentLoopReadSize = sc.read(totalReceiveBuff);
hasReadSize += currentLoopReadSize;

if (hasReadSize >= totalSize)
{
break;

} else
{
continue;
}
}
totalReceiveBuff.flip();

if (totalReceiveBuff.getInt() != 開始標識)
{
return;
}
int size = totalReceiveBuff.getInt();
byte[] bytes = new byte[size];
totalReceiveBuff.get(bytes);

if (totalReceiveBuff.getInt() != 結束標識)
{
return;
}
ByteBuffer realContentBuff = ByteBuffer.wrap(bytes);
int contentRealSize = realContentBuff.getShort();

byte[] stringBytes = new byte[contentRealSize];
realContentBuff.get(stringBytes);
handleServerCommand(new String(stringBytes, "UTF-8"));

} else
{
byte[] bytes = new byte[msgLength];
totalReceiveBuff.get(bytes);

if (totalReceiveBuff.getInt() != 結束標識)
{
return;
}
ByteBuffer realContentBuff = ByteBuffer.wrap(bytes);
int contentRealSize = realContentBuff.getShort();

byte[] stringBytes = new byte[contentRealSize];
realContentBuff.get(stringBytes);
handleServerCommand(new String(stringBytes, "UTF-8"));
}

// handle remain need to read

if (totalReceiveBuff.hasRemaining())
{
byte[] remainBytes = new byte[totalReceiveBuff.remaining()];
totalReceiveBuff.get(remainBytes);
totalReceiveBuff.clear();
totalReceiveBuff.put(remainBytes);

newParseSocketData(remainBytes.length,key);

} else
{
totalReceiveBuff.clear();
if(key.isReadable())

{
int pendingcounter = 0;
int available = 0;
while((pendingcounter++ < 20))

{
available = sc.read(totalReceiveBuff);
if (available <= 0)

{

try
{
Thread.sleep(100);

} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
continue;
}
else

{
newParseSocketData(available,key);
break;
}
}
}
}

}
在網絡不好的情況,其實你無法保證一次讀到的信息就是你要的那個正好的大小,你需要對于數據包進行積累,或者多讀了,需要繼續處理下次從socket讀到的剩余信息。
而flash 比較簡單
public function parseSocketData()

{

if(this.socketEchoSize==0)
{
if (socket.bytesAvailable < 8) return;
//包頭標志

if(socket.readInt()!=開始標識)
{
var bytes:ByteArray=new ByteArray();
socket.readBytes(bytes,0,socket.bytesAvailable);
this.socketEchoSize=0;
return;
}
this.socketEchoSize=socket.readInt();
}
//trace(socket.bytesAvailable, this.socketEchoSize);
//如果長度不夠就攢下來
if (socket.bytesAvailable < this.socketEchoSize + 4)

{
//socket.readShort();
//trace("data lost in transport:\n", socket.readUTFBytes(socket.bytesAvailable));
return;
}
var buffer : ByteArray = new ByteArray();
socket.readBytes(buffer, 0, this.socketEchoSize);
//包尾標志
if (socket.readInt() == 結束標識)

{
var sx:String = buffer.readUTFBytes(buffer.readShort());
//trace("received:\n" + sx);
this.receive(sx);
}
this.socketEchoSize=0;

if(socket.bytesAvailable>0)
{
this.parseSocketData();
}
}
人家flash的socket自己下面就幫你不斷的讀著,你每次之需要判斷byteAvailable屬性大于0否,就ok了。
java ,嚴謹。都需要在byteBuffer上面坐判斷。
最正確的寫法:

private void newParseSocketData() throws IOException
{
int count = 1;
int byteRead = 0;

Selector readSelector = null;
SelectionKey tmpKey = null;


try
{

while (count > 0)
{
count = sc.read(totalReceiveBuff); // [1]
if (count > -1)

{
byteRead += count;
}
}


if (byteRead == 0)
{
readSelector = Selector.open();
count = 1;
tmpKey = sc.register(readSelector, SelectionKey.OP_READ);
tmpKey.interestOps(tmpKey.interestOps() | SelectionKey.OP_READ);
int code = readSelector.select(200); // [3]
tmpKey.interestOps(
tmpKey.interestOps() & (~SelectionKey.OP_READ));

if (code == 0)
{
return; // Return on the main Selector and try again.
}

while (count > 0 )
{
count = sc.read(totalReceiveBuff); // [4]
if (count > -1)

{
byteRead += count;
}
}
}
}finally

{
if (tmpKey != null)

tmpKey.cancel();


if (readSelector != null)
{


try
{
readSelector.selectNow();


} catch (IOException ex)
{
;
}
readSelector.close();
}
}

totalReceiveBuff.flip();

while (totalReceiveBuff.remaining() > 8)
{


if (totalReceiveBuff.getInt() != 592464711)
{
return;
}
int size = totalReceiveBuff.getInt();

if (totalReceiveBuff.remaining() < size + 4)
{
int hasReadSize = byteRead;
int totalSize = size + 12;
totalReceiveBuff.position(totalReceiveBuff.limit());
totalReceiveBuff.limit(totalReceiveBuff.capacity());

while (true)
{
int currentLoopReadSize = sc.read(totalReceiveBuff);
hasReadSize += currentLoopReadSize;

if (hasReadSize >= totalSize)
{
break;

} else
{
continue;
}
}
totalReceiveBuff.flip();

if (totalReceiveBuff.getInt() != 592464711)
{
return;
}
int msgLength = totalReceiveBuff.getInt();
byte[] bytes = new byte[msgLength];
totalReceiveBuff.get(bytes);

if (totalReceiveBuff.getInt() != 1347110691)
{
return;
}
ByteBuffer realContentBuff = ByteBuffer.wrap(bytes);
int contentRealSize = realContentBuff.getShort();

byte[] stringBytes = new byte[contentRealSize];
realContentBuff.get(stringBytes);
handleServerCommand(new String(stringBytes, "UTF-8"));
}
else

{
byte[] bytes = new byte[size];
totalReceiveBuff.get(bytes);

if (totalReceiveBuff.getInt() != 1347110691)
{
return;
}
ByteBuffer realContentBuff = ByteBuffer.wrap(bytes);
int contentRealSize = realContentBuff.getShort();
byte[] stringBytes = new byte[contentRealSize];
realContentBuff.get(stringBytes);
handleServerCommand(new String(stringBytes, "UTF-8"));
}

}

totalReceiveBuff.clear();

}
posted on 2008-11-04 15:14
北國狼人的BloG 閱讀(460)
評論(1) 編輯 收藏