溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java如何使用線程池實(shí)現(xiàn)socket編程

發(fā)布時(shí)間:2022-03-30 16:50:30 來源:億速云 閱讀:187 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“Java如何使用線程池實(shí)現(xiàn)socket編程”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Java如何使用線程池實(shí)現(xiàn)socket編程”吧!

    前言

    以多個(gè)客戶端和一個(gè)服務(wù)端的socket通信為例,服務(wù)端啟動時(shí)創(chuàng)建一個(gè)固定大小的線程池。服務(wù)端每接收到一個(gè)連接請求后(通信任務(wù)),交給線程池執(zhí)行,任務(wù)類實(shí)現(xiàn)了Runnable接口,用于跟客戶端進(jìn)行讀寫操作,該類的對象作為任務(wù)通過execute(Runnable task)提交給線程池。

    一、一個(gè)簡單的C/S模型實(shí)現(xiàn)

    1.服務(wù)器

    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    public class Server {
        public static void main(String[] args) throws Exception {
            System.out.println("server start");
            ServerSocket server = new ServerSocket(1003);
            while (true) {
                Socket client = server.accept();
                InputStream input = client.getInputStream();
                byte[] b = new byte[8196];
                int len = input.read(b);
                System.out.println(new String(b, 0, len));
                if(new String(b).equals("close"))
                    break;
                client.close();
            }
            server.close();
        }
    }

    2.客戶端:

    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    public class Client {
        public static void main(String[] args) throws Exception {
            System.out.println("client start");
            Scanner scanner =new Scanner(System.in);
            Socket client =new Socket("localhost",1003);
            OutputStream out = client.getOutputStream();
            while (true) {
                String str = scanner.nextLine();
                out.write(str.getBytes());
            }
        }
    }

    此處只能服務(wù)器接收客戶端信息。

    二、線程池使用方法

    1.新建一個(gè)線程池

    ExecutorService pool = Executors.newFixedThreadPool(3);

    創(chuàng)建一個(gè)線程池,該線程池重用在共享無界隊(duì)列上運(yùn)行的固定數(shù)量的線程。 在任何時(shí)候,最多3個(gè)線程將是活動的處理任務(wù)。如果在所有線程都處于活動狀態(tài)時(shí)提交了其他任務(wù),它們將在隊(duì)列中等待,直到有線程可用。 如果任何線程在關(guān)閉之前的執(zhí)行過程中由于失敗而終止,如果需要執(zhí)行后續(xù)任務(wù),新的線程將取代它。 池中的線程將一直存在,直到顯式關(guān)閉。

    2.用Runnable接口實(shí)現(xiàn)線程

    private static class InnerThread implements Runnable{
    public void run();
    }

    3.創(chuàng)建線程對象并提交至線程池執(zhí)行

    InnerThread innerThread = new InnerThread();
    pool.execute(innerThread);

    三、結(jié)合起來

    當(dāng)新的連接建立時(shí)創(chuàng)建一個(gè)新線程并提交到線程池

    while(true){
                    Socket clientSocket = server.accept();
                    InnerThread innerThread = new InnerThread(clientSocket);
                    pool.execute(innerThread);
                }

    run方法為如何處理新連接,以及客戶端和服務(wù)端的信息交流。

    四、使用新的輸入輸出流

    由于OutputStream和InputStream類有方法沒有實(shí)現(xiàn)或是實(shí)現(xiàn)的不是很好,所以我們選擇使用
    BufferedReader,PrintWriter類來實(shí)現(xiàn)通信。

    服務(wù)器:

    BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
    while(true){
                        String buf = br.readLine();
                        System.out.println(Thread.currentThread().getName()+" client: " + buf);
                        if(buf.equals("close")){
                            break;
                        }
                        pw.println("response:"+buf);
                        pw.flush();
                    }
                    System.out.println("close client");
                    br.close();
                    pw.close();
                    clientSocket.close();

    客戶端:

    BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                while(true){
                    System.out.print("client: ");
                    String buf = sc.nextLine();
                    pw.println(buf);
                    pw.flush();
                    if(buf.equals("close")){
                        break;
                    }
                    buf= br.readLine();
                    System.out.println("server: " + buf);
                    if(buf.equals("close")){
                        break;
                    }
                }
                br.close();
                pw.close();
                sc.close();
                clientSocket.close();

    這樣子就能較為方便的實(shí)現(xiàn)服務(wù)端向客戶端發(fā)送信息。

    感謝各位的閱讀,以上就是“Java如何使用線程池實(shí)現(xiàn)socket編程”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Java如何使用線程池實(shí)現(xiàn)socket編程這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI