【簡單封裝】TCP服務器

一、PZHelp_TCPServer類(線程)

public class PZHelp_TCPServer extends Thread {
    private static final String TAG = "PZHelp_TCPServer";

    //Server
    private ServerSocket                  serverSocket;
    private int                           port;
    //TCPServer標誌位
    private boolean                       isTCPServerOpen = false;
    //存放所有客戶端線程
    private ArrayList<ServerSocketThread> clientList      = new ArrayList<>();
    //回調
    private ReceiveListener               listener;

    public PZHelp_TCPServer(int port, ReceiveListener listener) {
        this.port = port;
        this.listener = listener;
    }

    @Override
    public synchronized void start() {
        isTCPServerOpen = true;
        super.start();
    }

    /**
     * TCPServer主體
     */
    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(port);
            while (isTCPServerOpen) {
                Socket socket = serverSocket.accept();
                if (socket != null) {
                    Log.d(TAG, "run: 新的客戶端:" + socket);
                    new ServerSocketThread(socket);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取當前Server的連接數
     *
     * @return 連接數
     */
    public int getClientNum() {
        return clientList.size();
    }

    /**
     * 關閉TCPServer
     */
    void close() {
        isTCPServerOpen = false;
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * client線程
     */
    public class ServerSocketThread extends Thread {
        private Socket      socket;
        private InputStream is = null;
        private PrintWriter pw = null;

        //接收到的數據
        String receive;
        //接收到的數據長度
        int    length;
        byte[] buff = new byte[2048];

        ServerSocketThread(Socket socket) {
            this.socket = socket;
            try {
                socket.setSoTimeout(8000);
                is = socket.getInputStream();
                pw = new PrintWriter(socket.getOutputStream(), true);
                start();
            } catch (IOException e) {
                listener.onFail(e.getMessage());
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            clientList.add(this);
            while (isTCPServerOpen && !socket.isClosed() && !socket.isInputShutdown()) {
                try {
                    if ((length = is.read(buff)) != -1) {
                        //連接正常,接收到數據
                        receive = new String(buff, 0, length, "GBK");
                        listener.Receive(socket, receive);
                    } else {
                        Log.d(TAG, "客戶端斷開,關閉通訊線程: " + this);
                        break;
                    }
                } catch (SocketTimeoutException e) {
                    Log.d(TAG, "長時間未收到客戶端數據,關閉通訊線程:" + this);
                    break;
                } catch (IOException e) {
                    listener.onFail("接收數據異常");
                    e.printStackTrace();
                }
            }

            //關閉通訊和線程
            try {
                socket.close();
                clientList.remove(this);
            } catch (IOException e) {
                listener.onFail("關閉與客戶端之間的通訊出現異常");
                e.printStackTrace();
            }
        }

        /**
         * 發送信息
         *
         * @param msg 信息
         * @return 是否發送成功
         */
        public boolean send(String msg) {
            if (!socket.isClosed()) {
                pw.println(msg);
                pw.flush();
                return true;
            }
            return false;
        }
    }

    /**
     * 回調
     */
    public interface ReceiveListener {
        void onFail(String err);

        void Receive(Socket socket, String receive);
    }
}

二、主函數使用

tcpServer = new PZHelp_TCPServer(8000, new PZHelp_TCPServer.ReceiveListener() {
    @Override
    public void onFail(String err) {
        Log.d(TAG, "onFail: " + err);
    }

    @Override
    public void Receive(Socket socket, String receive) {
        Log.d(TAG, "接收到來自" + socket+ "的信息:" + receive);
    }
});
tcpServer.start();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章