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 阅读(457)
评论(1) 编辑 收藏