JAVA造輪子之-Socket操做工具類

用java.net.Socket進行Socket操做工具類
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * @author JL
 * @version V1.0
 * @Description 用java.net.Socket進行Socket操做工具類
 */
public class SocketUtils {

    private static final String ENCODING = "UTF-8";

    public static void listen(final int port, String content, SocketFunction function) throws IOException{
        ServerSocket serverSocket = null ;
        Socket socket = null;
        try {
            serverSocket = createServer(port);
            socket = createServerSocket(serverSocket);
            //一般獲取到socket鏈接後,都是分配一個線程來處理客戶端
            WorkClass workClass = new WorkClass(socket, content, function);
            workClass.work();
        }catch(IOException ioe){
            ioe.printStackTrace();
            throw ioe;
        }finally{
            clientClose(socket);
            //關閉服務端
            serverClose(serverSocket);
        }
    }

    static class WorkClass{
        private Socket socket ;
        private String content;
        private SocketFunction function;
        public WorkClass(Socket socket, String content, SocketFunction function){
            this.socket = socket;
            this.content = content;
            this.function = function;
        }

        public void work() throws IOException {
            String msg = null;
            InputStream in = null;
            OutputStream out = null;
            try {
                in = socket.getInputStream();
                msg = input(in);
                out = socket.getOutputStream();
                output(out, content);
                function.callback(msg);
            }finally{
                //關閉輸入輸出流
                streamClose(in, out);
            }
        }
    }

    public static void send(String host, int port, String content, SocketFunction function) throws IOException{
        Socket socket = null;
        String msg = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            socket = createClientSocket(host, port);
            out = socket.getOutputStream();
            output(out, content);
            socket.shutdownOutput();//輸出完後,須要關閉socket的輸出通道,表示不存向服務端輸出內容
            in = socket.getInputStream();
            msg = input(in);
            function.callback(msg);
        }catch(UnknownHostException uhe){
            uhe.printStackTrace();
            throw new IOException("主機鏈接建立異常:" + uhe.getMessage());
        }catch(IOException ioe){
            ioe.printStackTrace();
            throw ioe;
        }finally{
            streamClose(in, out);
            clientClose(socket);
        }
    }

    public static void streamClose(InputStream in, OutputStream out){
        //IOUtils.closeQuietly(in); 可用IOUtils工具類關閉流
        if (in != null){
            try {
                in.close();
            }catch(IOException ioe){
                System.out.println("關閉輸入流異常:" + ioe.getMessage());
            }
        }
        if (out != null){
            try {
                out.flush();
                out.close();
            }catch(IOException ioe){
                System.out.println("關閉輸出流異常:" + ioe.getMessage());
            }
        }
    }

    private static ServerSocket createServer(int port) throws IOException {
        System.out.println("監聽端口號:" + port);
        return new ServerSocket(port);
    }

    private static Socket createServerSocket(ServerSocket serverSocket) throws IOException {
        Socket socket = serverSocket.accept();
        System.out.println("獲取到客戶端鏈接:" + socket.getInetAddress().getHostAddress());
        return socket;
    }

    private static Socket createClientSocket(String host, int port) throws UnknownHostException, IOException {
        return new Socket(host, port);
    }

    private static void serverClose(ServerSocket server) {
        if (server != null && !server.isClosed()){
            try{
                server.close();
            }catch(IOException ioe){
                System.out.println("服務關閉異常:" + ioe.getMessage());
            }
        }
    }

    private static void clientClose(Socket socket){
        if (socket != null && !socket.isClosed()){
            try{
                socket.close();
            }catch(IOException ioe){
                System.out.println("Socket關閉異常:" + ioe.getMessage());
            }
        }
    }

    public static OutputStream output(OutputStream out, String content) throws IOException {
        try{
            out.write(content.getBytes(ENCODING));
        }finally{
            return out;
        }
    }

    public static String input(InputStream in) throws IOException {
        int len;
        char[] b = new char[1024];
        StringBuilder sb = new StringBuilder();
        BufferedReader reader ;
        try {
            //以字符流爲主,如需字節流,則不須要BufferedReader和InputStreamReader,能夠直接從InputStream中獲取或採用對應緩衝包裝類
            reader = new BufferedReader(new InputStreamReader(in, ENCODING));
            while ((len = reader.read(b)) != -1) {
                sb.append(b, 0, len);
            }
            //reader.close();
        }finally{
        }
        return sb.toString();
    }

    public interface SocketFunction{
        void callback(String msg);
    }

    public static void main(String[] args) throws IOException{
        String data = "這是測試數據:";
        //測試時,請分別單獨啓動send和listen方法
        //客戶端
//        send("127.0.0.1",8111, "this is client test", new SocketFunction(){
//            @Override
//            public void callback(String msg) {
//                System.out.println(data + msg);
//            }
//        });

        //服務端
        listen(8111, "this is server test", new SocketFunction() {
            @Override
            public void callback(String msg) {
                System.out.println(data + msg);
            }
        });
    }

}

 

說明:java

作過項目的人都知道,不少寫過的可重複利用的代碼塊或有用的工具類沒有怎麼整理,當須要的時候,又得打開項目查找一翻,雖然功能開發不難,可是又得花時間成本去寫去測試,這樣的重複造輪子的事情太屢次了;所以不如把輪子保留,供你們一塊兒使用;app

1.這個輪子能夠有:須要使用的時候確實還不存在這個組件。
2.我須要的時候輪子不在:每一種技術或工具產生都有它的項目背景,當代碼寫在項目裏的時候,我知道有這個東西,當換了一個項目或公司後,沒有備份也沒有記錄,這個時候你不在了,又得花時間手打一遍;
3.我不知道是否是造輪子:大多數狀況下初學者很難分清楚本身是否是在重複造輪子,事實上造輪子不是我目的。個人目的是完成工做任務,任務完成的速度越快越好,質量越高越好。而不是去判斷本身在不在造輪子。
4.不想重複花時間造輪子:有時候還會碰到一些並不困難可是很佔時間的東西,固然有現成的輪子是花時間最少的;
5.我就是想學習輪子:初學者的並非在重複造輪子,而是學習後以提升爲本身的知識與技能。socket

輪子有過測試,但不免有失誤,若有錯誤處,還敬請指出;ide

相關文章
相關標籤/搜索