Java Socket:シングルスレッド/マルチスレッド/スレッドプールサーバSocketプログラミング

12209 ワード

Socketは、ネットワークを読み書き可能なバイトストリームとして抽象化し、ユーザーに最下位の複雑な詳細を隠す.JavaはSocketオブジェクトを使用してクライアントネットワークプロセスを実現する:接続を要求し、データを送信/受信し、リンクを閉じる;サービス・エンド・ネットワーク・プロセスは、ServerSocketオブジェクトを使用して実現されます.ポート/ローカル・インタフェースのバインド、リクエストのリスニング、リクエストの受信、データの受信/送信、接続のクローズです.以下では,シミュレーションdaytimeプロトコルサービス側のプログラムをまとめ,それぞれ単一スレッド,マルチスレッド,固定スレッドプール方式で実現し,各実現方式はアプリケーションシーンを無視した場合では伯仲し難いが,筆者から見れば簡単なdaytimeサーバの単一スレッド実現には十分であるが,どのシーンでもスレッド数を制限しない実現方式は用いない.
  • SingleThreadServer.javaシングルスレッドサービス方式:
  • import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Date;
    
    /**
     * Created by Cheney Hwang on 2017/5/1.
     *              ,        
     */
    public class SingleThreadServer {
        public final static int PORT=5555;
    
        public static void main(String[] args){
            try(ServerSocket server=new ServerSocket(PORT)){
                while(true){
                    try(Socket socket=server.accept()){
                        Writer out=new OutputStreamWriter(socket.getOutputStream(),"ASCII");
                        Date now=new Date();
                        out.write(now.toString()+"\r
    "
    ); // , out.flush(); out.close(); }catch (IOException ex){ // } } }catch (IOException ex){// System.err.println(ex); } } }
  • MultiThreadServer.java無制限数マルチスレッドサービス方式:
  • import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Date;
    
    /**
     * Created by Cheney Hwang on 2017/5/1.
     *                  ,                 
     *                ,    DOS  
     */
    public class MultiThreadServer {
        public final static int PORT=5555;
    
        public static void main(String[] args){
            try(ServerSocket server=new ServerSocket(PORT)){
                while(true) {
                    try {
                        Socket client = server.accept();
                        Thread task = new TimeThread(client);
                        task.start();
    
                    } catch (IOException ex) {
                        //      
                    }
                }
            }catch (IOException ex){//               
                System.err.println(ex);
            }
        }
    
        private static class TimeThread extends Thread{
            private Socket client;
    
            public TimeThread(Socket client){
                this.client=client;
            }
    
            @Override
            public void run(){
                try{
                    Writer out=new OutputStreamWriter(client.getOutputStream());
                    Date now=new Date();
                    out.write(now.toString()+"\r
    "
    ); // , out.flush(); out.close(); }catch (IOException ex){ System.err.println(ex); }finally { try { client.close(); }catch (IOException ex){ // } } } } }
  • FixedPoolServer.java固定数スレッドプールサービス方式:
  • import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.Writer;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Date;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Created by Cheney Hwang on 2017/5/1.
     *                       ,        
     */
    public class FixedPoolServer {
        public final static int PORT = 5555;
    
        public static void main(String[] args) {
            ExecutorService pool = Executors.newFixedThreadPool(50);
            //       
    
            try (ServerSocket server = new ServerSocket(PORT)) {
                while (true) {
                    try {
                        Socket client = server.accept();
                        Callable task = new TimeThread(client);
                        pool.submit(task);
    
                    } catch (IOException ex) {
                        //      
                    }
                }
            } catch (IOException ex) {//               
                System.err.println(ex);
            }
        }
    
        private static class TimeThread implements Callable<Void> {
            private Socket client;
    
            public TimeThread(Socket client) {
                this.client = client;
            }
    
            @Override
            public Void call() {
                try {
                    Writer out = new OutputStreamWriter(client.getOutputStream());
                    Date now = new Date();
                    out.write(now.toString() + "\r
    "
    ); // , out.flush(); out.close(); } catch (IOException ex) { System.err.println(ex); } finally { try { client.close(); } catch (IOException ex) { // } } return null; } } }
  • 以下は、クライアントの例です.
  • import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.net.Socket;
    
    /**
     * Created by Cheney Hwang on 2017/5/1.
     */
    public class Client {
        public final static String HOST="localhost";
        public final static int PORT=5555;
    
        public static void main(String[] args){
            try(Socket client=new Socket(HOST,PORT)){//           
                Reader in=new InputStreamReader(client.getInputStream());
                int c;
                StringBuilder builder=new StringBuilder();
                while ((c=in.read())!=-1){
                    builder.append((char)c);
                }
                System.out.println(builder.toString());
                in.close();
    
            }catch (IOException ex){
                System.err.println("Cant connect to server!");
            }
        }
    }