java flash tcp字节流通信(四)-java 服务端(粘包/半包处理)

来源:互联网 发布:ubuntu怎么读u盘 编辑:程序博客网 时间:2024/05/17 00:01

package com.net.test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import com.net.tcp.DataCache;
import com.net.tcp.DataPack;
import com.net.tcp.StreamObjectManager;

/**
 *
 * nio通信服务端
 *
 */
public class NIOServer {
 private ServerSocketChannel serverSokcetChannel;
 private Selector selector;

 public NIOServer(int port) throws Exception{
  serverSokcetChannel = ServerSocketChannel.open();
  serverSokcetChannel.configureBlocking(false);
  serverSokcetChannel.socket().bind(new InetSocketAddress(port));
  selector = Selector.open();
  serverSokcetChannel.register(selector, SelectionKey.OP_ACCEPT);
  listen();
 }
 
 public void listen(){
  Set<SelectionKey> keys = null;
  Iterator<SelectionKey> keyIt = null;
  SelectionKey key = null;
  while(true){
   try {
    selector.select();
    keys = selector.selectedKeys();
    keyIt = keys.iterator();
    while(keyIt.hasNext()){
     key = keyIt.next();
     keyIt.remove();
     dealKey(key);
    }
   } catch (Exception e) {
    e.printStackTrace();
    if(key != null)
     closeChannel((SocketChannel)key.channel());
   }
  }
 }
 
 public void dealKey(SelectionKey key) throws Exception{
  if(key.isAcceptable()){
   ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
   SocketChannel channel = serverChannel.accept();
   channel.configureBlocking(false);
   DataCache[] caches = {new DataCache(1024), new DataCache(0)};
   channel.register(selector, SelectionKey.OP_READ, caches);
  }else if(key.isReadable()){
   SocketChannel channel = (SocketChannel)key.channel();
   DataCache[] cache = (DataCache[])key.attachment();
   if(cache[0].read(channel) > 0){
    DataPack pack = null;
    boolean sign = false;
    while((pack = cache[0].poll()) != null){
     cache[1].push(pack);
     sign = true;
    }
    if(sign){
     key.interestOps(SelectionKey.OP_WRITE);
    }
   }else{
    closeChannel(channel);
   }
//   ByteBuffer buffer = ByteBuffer.allocate(1024);
//   if(channel.read(buffer) > 0){
//    buffer.flip();
//    int size = buffer.getInt();
//    byte[] bytes = new byte[size];
//    buffer.get(bytes);
//    DataPack pack = new DataPack();
//    pack.getContent().putBytes(bytes);
//    pack.filp();
//    Object object = pack.getObject();
//    key.interestOps(SelectionKey.OP_WRITE);
//    key.attach(object);
//   }else{
//    closeChannel(channel);
//   }
  }else if(key.isWritable()){
   SocketChannel channel = (SocketChannel)key.channel();
   DataCache[] cache = (DataCache[])key.attachment();
   if(cache[1].write(channel)){
    key.interestOps(SelectionKey.OP_READ);
   }
//   DataPack pack = new DataPack();
//   pack.putObject(key.attachment(), DataType.TYPE_OBJECT);
//   pack.filp();
//   channel.write(pack.getHead().getContent());
//   ByteBuffer buffer = pack.getContent().current(false);
//   while(buffer != null){
//    channel.write(buffer);
//    buffer = pack.getContent().next(false);
//   }
//   key.interestOps(SelectionKey.OP_READ);
  }
 }
 
 public void closeChannel(SocketChannel channel){
  if(channel != null){
   SelectionKey key = channel.keyFor(selector);
   if(key != null){
    key.cancel();
   }
   try {
    channel.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
 
 public static void main(String args[]) throws Exception{
  StreamObjectManager.init("com.net.test.*");
  new NIOServer(2345);
 }
}

原创粉丝点击