最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

教你怎么用java實現(xiàn)客戶端與服務器一問一答

 更新時間:2021年04月30日 10:39:18   作者:小樓夜聽雨QAQ  
這篇文章主要介紹了教你怎么用java實現(xiàn)客戶端與服務器一問一答,文中有非常詳細的代碼示例,對正在學習java的小伙伴們有非常好的幫助,需要的朋友可以參考下

運行效果

開啟多個客戶端

服務端效果:

客戶端效果:

當一個客戶端斷開連接:

代碼

因為代碼中有注釋,我就直接貼上來了

服務端:

package com.dayrain.server;
 
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
 
public class NioServer {
    /**端口**/
    private static final int PORT = 8081;
    /**buffer大小**/
    private static final int DEFAULT_BUFFER_SIZE = 1024;
    private final Selector selector;
    private final ByteBuffer readBuffer = ByteBuffer.allocate(NioServer.DEFAULT_BUFFER_SIZE);
    private final ByteBuffer writeBuffer = ByteBuffer.allocate(NioServer.DEFAULT_BUFFER_SIZE);
 
    private static int count = 0;
 
    public static void main(String[] args) throws IOException {
        new NioServer().start();
    }
 
    public NioServer() throws IOException {
        //創(chuàng)建一個服務端channel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
 
        //設置為非阻塞
        serverSocketChannel.configureBlocking(false);
 
        //獲取服務器socket
        ServerSocket socket = serverSocketChannel.socket();
        //綁定ip和端口
        socket.bind(new InetSocketAddress(NioServer.PORT));
 
        //創(chuàng)建多路復用選擇器,并保持打開狀態(tài),直到close
        selector = Selector.open();
 
        //將服務器管道注冊到selector上,并監(jiān)聽accept事件
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("server start on port: " + NioServer.PORT);
        start();
    }
 
    public void start() throws IOException {
 
        //selector是阻塞的,直到至少有一個客戶端連接。
        while (selector.select() > 0) {
            //SelectionKey是channel想Selector注冊的令牌,可以通過chancel取消(不是立刻取消,會放進一個cancel list里面,下一次select時才會把它徹底刪除)
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                iterator.remove();
                //當這個key的channel已經(jīng)準備好接收套接字連接
                if(selectionKey.isAcceptable()) {
                    connectHandle(selectionKey);
                }
 
                //當這個key的channel已經(jīng)準備好讀取數(shù)據(jù)時
                if(selectionKey.isReadable()) {
                    readHandle(selectionKey);
                }
            }
        }
    }
 
    /**
     * 處理連接
     * @param selectionKey
     */
    private void connectHandle(SelectionKey selectionKey) throws IOException {
        //注意,服務端用的是ServerSocketChannel,BIO中是ServerSocket
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
        SocketChannel socketChannel = serverSocketChannel.accept();
        if(socketChannel == null) {
            return;
        }
        socketChannel.configureBlocking(false);
        socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
 
        System.out.println("客戶端連接成功,當前總數(shù):" + (++count));
 
        writeBuffer.clear();
        writeBuffer.put("連接成功".getBytes(StandardCharsets.UTF_8));
        writeBuffer.flip();
        socketChannel.write(writeBuffer);
    }
 
    /**
     * 讀取數(shù)據(jù)
     * @param selectionKey
     */
    private void readHandle(SelectionKey selectionKey){
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        try {
            readBuffer.clear();
            int read = socketChannel.read(readBuffer);
            if(read > 0) {
                readBuffer.flip();
                String receiveData = StandardCharsets.UTF_8.decode(readBuffer).toString();
 
                System.out.println("收到客戶端消息: " + receiveData);
 
                writeBuffer.clear();
                writeBuffer.put(receiveData.getBytes(StandardCharsets.UTF_8));
                writeBuffer.flip();
                socketChannel.write(writeBuffer);
            }
 
        }catch (Exception e) {
            try {
                socketChannel.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
            System.out.println("客戶端斷開了連接~~");
            count--;
        }
    }
}

客戶端

package com.dayrain.client;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
 
public class NioClient {
 
    private static final int PORT = 8081;
    private static final int DEFAULT_BUFFER_SIZE = 1024;
    private final Selector selector;
    private final ByteBuffer readBuffer = ByteBuffer.allocate(NioClient.DEFAULT_BUFFER_SIZE);
    private final ByteBuffer writeBuffer = ByteBuffer.allocate(NioClient.DEFAULT_BUFFER_SIZE);
 
    public static void main(String[] args) throws IOException {
        NioClient nioClient = new NioClient();
 
        //終端監(jiān)聽用戶輸入
        new Thread(nioClient::terminal).start();
 
        //這個方法是阻塞的,要放在最后
        nioClient.start();
    }
 
    public NioClient() throws IOException {
        selector = Selector.open();
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(InetAddress.getLocalHost(), NioClient.PORT));
        socketChannel.configureBlocking(false);
        socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    }
 
    public void start() throws IOException {
        while (selector.select() > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                //拿到selectionKey后要刪除,否則會重復處理
                iterator.remove();
                if(selectionKey.isReadable()) {
                    handleRead(selectionKey);
                }
 
                //只要連接成功,selectionKey.isWritable()一直為true
                if(selectionKey.isWritable()) {
                    handleWrite(selectionKey);
                }
            }
        }
    }
 
    /**
     * 監(jiān)聽寫操作
     */
    private void handleWrite(SelectionKey selectionKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
 
        // writeBuffer有數(shù)據(jù)就直接寫入,因為另開了線程監(jiān)聽用戶讀取,所以要上鎖
        synchronized (writeBuffer) {
            writeBuffer.flip();
            while (writeBuffer.hasRemaining()) {
                socketChannel.write(writeBuffer);
            }
            writeBuffer.compact();
        }
 
    }
 
    /**
     * 監(jiān)聽讀操作
     */
    private void handleRead(SelectionKey selectionKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        readBuffer.clear();
        socketChannel.read(readBuffer);
 
        readBuffer.flip();
        String res = StandardCharsets.UTF_8.decode(readBuffer).toString();
        System.out.println("收到服務器發(fā)來的消息: " + res);
        readBuffer.clear();
    }
 
    /**
     * 監(jiān)聽終端的輸入
     */
    private void terminal() {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        try {
            String msg;
            while ((msg = bufferedReader.readLine()) != null) {
                synchronized (writeBuffer) {
                    writeBuffer.put((msg + "\r\n").getBytes(StandardCharsets.UTF_8));
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
}

到此這篇關于教你怎么用java實現(xiàn)客戶端與服務器一問一答的文章就介紹到這了,更多相關java實現(xiàn)客戶端與服務器一問一答內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Win10 Java jdk14.0.2安裝及環(huán)境變量配置詳細教程

    Win10 Java jdk14.0.2安裝及環(huán)境變量配置詳細教程

    這篇文章主要介紹了Win10 Java jdk14.0.2安裝及環(huán)境變量配置,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • 詳解Java前綴樹Trie的原理及代碼實現(xiàn)

    詳解Java前綴樹Trie的原理及代碼實現(xiàn)

    Trie又被稱為前綴樹、字典樹。Trie利用字符串的公共前綴來高效地存儲和檢索字符串數(shù)據(jù)集中的關鍵詞,最大限度地減少無謂的字符串比較,其核心思想是用空間換時間。本文主要介紹了Trie的原理及實現(xiàn),感興趣的可以了解一下
    2022-11-11
  • 關于junit測試需要的依賴

    關于junit測試需要的依賴

    這篇文章主要介紹了關于junit測試需要的依賴,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 淺談Springmvc中的頁面跳轉(zhuǎn)問題

    淺談Springmvc中的頁面跳轉(zhuǎn)問題

    這篇文章主要介紹了淺談Springmvc中的頁面跳轉(zhuǎn)問題,具有一定參考價值,需要的朋友可以了解下。
    2017-12-12
  • springboot如何配置嵌套map和list參數(shù)

    springboot如何配置嵌套map和list參數(shù)

    這篇文章主要介紹了springboot如何配置嵌套map和list參數(shù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • IDEA不編譯除了.java之外的文件的解決辦法(推薦)

    IDEA不編譯除了.java之外的文件的解決辦法(推薦)

    這篇文章主要介紹了IDEA不編譯除了.java之外的文件的解決辦法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • 如何利用Java使用AOP實現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換

    如何利用Java使用AOP實現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換

    這篇文章主要介紹了如何利用Java使用AOP實現(xiàn)數(shù)據(jù)字典轉(zhuǎn)換,AOP也是我們常說的面向切面編程,AOP在我們開發(fā)過程中應用也比較多,在這里我們就基于AOP來實現(xiàn)一個數(shù)據(jù)字典轉(zhuǎn)換的案例
    2022-06-06
  • Java面試題沖刺第二十七天--JVM2

    Java面試題沖刺第二十七天--JVM2

    這篇文章主要為大家分享了最有價值的三道關于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Spring中ThreadLocal的解析

    Spring中ThreadLocal的解析

    這篇文章主要介紹了Spring中ThreadLocal的解析,Spring通過各種DAO模板類降低了開發(fā)者使用各種數(shù)據(jù)持久技術的難度。這些模板類都是線程安全的,也就是說,多個DAO可以復用同一個模板實例而不會發(fā)生沖突,下面一起進入文章學子詳細內(nèi)容吧
    2022-01-01
  • java微信紅包實現(xiàn)算法

    java微信紅包實現(xiàn)算法

    這篇文章主要為大家詳細介紹了java微信紅包實現(xiàn)算法,列出紅包的核心算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02

最新評論

镇坪县| 河间市| 营口市| 花莲县| 德庆县| 宜宾市| 同仁县| 枣阳市| 紫金县| 台北县| 开鲁县| 安国市| 富川| 靖宇县| 台中市| 甘南县| 安远县| 咸宁市| 东兰县| 衡东县| 涟水县| 东阳市| 梨树县| 荃湾区| 武安市| 米林县| 垫江县| 孟津县| 抚远县| 肃宁县| 周至县| 陇南市| 余庆县| 突泉县| 惠水县| 武汉市| 永康市| 桐梓县| 邢台县| 天长市| 宁晋县|