EchoServer.java (阻塞模式)

來源:互聯網
上載者:User

標籤:pen   bin   ret   org   pool   r.java   編程   oca   decode   

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

public class EchoServer {
  private int port=8000;
  private ServerSocketChannel serverSocketChannel = null;
  private ExecutorService executorService;
  private static final int POOL_MULTIPLE = 4;

  public EchoServer() throws IOException {
    executorService= Executors.newFixedThreadPool(
        Runtime.getRuntime().availableProcessors() * POOL_MULTIPLE);
    serverSocketChannel= ServerSocketChannel.open();
    serverSocketChannel.socket().setReuseAddress(true);
    serverSocketChannel.socket().bind(new InetSocketAddress(port));
    System.out.println("伺服器啟動");
  }

  public void service() {
    while (true) {
      SocketChannel socketChannel=null;
      try {
        socketChannel = serverSocketChannel.accept();
        executorService.execute(new Handler(socketChannel));
      }catch (IOException e) {
         e.printStackTrace();
      }
    }
  }

  public static void main(String args[])throws IOException {
    new EchoServer().service();
  }
}

class Handler implements Runnable{
  private SocketChannel socketChannel;
  public Handler(SocketChannel socketChannel){
    this.socketChannel=socketChannel;
  }
  public void run(){
    handle(socketChannel);
  }

  public void handle(SocketChannel socketChannel){
    try {
        Socket socket=socketChannel.socket();
        System.out.println("接收到客戶串連,來自: " +
        socket.getInetAddress() + ":" +socket.getPort());

        BufferedReader br =getReader(socket);
        PrintWriter pw = getWriter(socket);

        String msg = null;
        while ((msg = br.readLine()) != null) {
          System.out.println(msg);
          pw.println(echo(msg));
          if (msg.equals("bye"))
            break;
        }
      }catch (IOException e) {
         e.printStackTrace();
      }finally {
         try{
           if(socketChannel!=null)socketChannel.close();
         }catch (IOException e) {e.printStackTrace();}
      }
  }

  private PrintWriter getWriter(Socket socket)throws IOException{
    OutputStream socketOut = socket.getOutputStream();
    return new PrintWriter(socketOut,true);
  }
  private BufferedReader getReader(Socket socket)throws IOException{
    InputStream socketIn = socket.getInputStream();
    return new BufferedReader(new InputStreamReader(socketIn));
  }

  public String echo(String msg) {
    return "echo:" + msg;
  }
}





/****************************************************
 * 孫衛琴                                     *
 * 來源:<<Java網路編程精解>>                       *
 * 支援人員網址:www.javathinker.org                *
 ***************************************************/

 

EchoServer 類的構造負責建立線程池,啟動伺服器,把它綁定到一個本地連接埠。EchoServer類的service()方法負責接收客戶的串連。每接收一個客戶串連,就把它交給線程池來處理,線程池取出一個閒置線程,來執行Handler對象的run()方法。Handler類的handle()負責與客戶通訊。該方法先獲得與SocketChannel關聯的Socket對象,然後從Socket對象中得到輸入資料流與輸出資料流,再接收和發送資料。
    SocketChanle實際上也是提供了read(ByteBuffer buffer),但是通過它來讀取一行字元比較麻煩。一下radLine()方法就通過SocketChannel的read(ByteBuffer buffer)方法來讀取一行字串。它的作用與BufferReader的readLine()方法等價的。

 

 

//*******************

public String readLine(SocketChannel socketChannel)throws IOException{
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    ByteBuffer tempBuffer =ByteBuffer.allocate(1);
    boolean isLine = false;
    boolean isEnd = false;
    String data = null;
    while(!isLine && !isEnd){
        tempBuffer.clear();
        int n = socketChannel.read(tempBuffer);
        if(n==-1){
            isEnd = true;
            break;
        }
        if(n==0) continue;
        tempBuffer.flip();
        buffer.put(tempBuffer);
        buffer.flip();
        Charset charset  = Charset.forName("GBK");
        CharBuffer charBuffer = charset.decode(buffer);
        data = charBuffer.toString();
        if(data.indexOf("\r\n")!=-1){
            isLine = true;
            data = data.substring(0,data.indexOf("\r\n"));
            break;
        }
        buffer.position(buffer.limit());
        buffer.limit(buffer.capacity());
    }
    return data;

 

EchoServer.java (阻塞模式)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.