服务器端修正(1)

这是一个相当精辟的一个程序,值得继续学习这个程序

package nonblock;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;

public class EchoServer {
 private Selector selector = null;
 private ServerSocketChannel serverSocketChannel = null;
 private int port = 8000;
 private Charset charset = Charset.forName("GBK");
 
 public EchoServer()throws IOException{
  selector = Selector.open();
  serverSocketChannel = ServerSocketChannel.open();
  //使得在同一个主机上关闭了服务器程序,紧接着再启动该服务器程序时,
  //可以顺利绑定到同步端口
  serverSocketChannel.socket().setReuseAddress(true);
  serverSocketChannel.configureBlocking(false);
  serverSocketChannel.socket().bind(new InetSocketAddress(port));
  System.out.println("服务器启动");
 }
 
 public void service()throws IOException{
  serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  while(selector.select()>0){
   Set readyKeys = selector.selectedKeys();
   Iterator it = readyKeys.iterator();
   while(it.hasNext()){
    SelectionKey key = null;
    try{
     key = (SelectionKey)it.next();
     it.remove();
     
     if(key.isAcceptable()){
      ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
      SocketChannel socketChannel = (SocketChannel)ssc.accept();
      System.out.println("接收到客户连接,来自:"+
        socketChannel.socket().getInetAddress()+
        ";"+socketChannel.socket().getPort());
      socketChannel.configureBlocking(false);
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      socketChannel.register(selector, SelectionKey.OP_READ|
              SelectionKey.OP_WRITE);
     }
     if(key.isReadable()){
      receive(key);
     }
     if(key.isWritable()){
      send(key);
     }
    }catch(IOException e){
     e.printStackTrace();
     try{
      if(key != null){
       key.cancel();
       key.channel().close();
      }
     }catch(Exception ex){
      ex.printStackTrace();
     }
    }
   }//#while
  }//#while
 }
 
 public void send(SelectionKey key)throws IOException{
  ByteBuffer buffer = (ByteBuffer)key.attachment();
  SocketChannel socketChannel = (SocketChannel)key.channel();
  buffer.flip();
  String data = decode(buffer);
  if(data.indexOf("/r/n") == -1) return;
  String outputData = data.substring(0, data.indexOf("/n")+1);
  System.out.println(outputData);
  ByteBuffer outputBuffer = encode("echo:"+outputData);
  while(outputBuffer.hasRemaining())
   socketChannel.write(outputBuffer);
  
  ByteBuffer temp = encode(outputData);
  buffer.position(temp.limit());
  buffer.compact();
  
  if(outputData.equals("bye/r/n")){
   key.cancel();
   socketChannel.close();
   System.out.println("关闭与客户的连接");
  }
 }

 public void receive(SelectionKey key)throws IOException{
  ByteBuffer buffer = (ByteBuffer)key.attachment();
  
  SocketChannel socketChannel = (SocketChannel)key.channel();
  ByteBuffer readBuffer = ByteBuffer.allocate(32);
  socketChannel.read(readBuffer);
  readBuffer.flip();
  
  buffer.limit(buffer.capacity());
  buffer.put(readBuffer);
 }
 
 private ByteBuffer encode(String outputData) {
  return charset.encode(outputData);
 }

 private String decode(ByteBuffer buffer) {
  CharBuffer charBuffer = charset.decode(buffer);
  return charBuffer.toString();
 }
 
 public static void main(String[] args)throws Exception{
  EchoServer server = new EchoServer();
  server.service();
 }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值