在做關於NIO TCP編程小案例時遇到無法監聽write的問題,沒想到只是我的if語句的位置放錯了位置,哎,看了半天沒看出來

来源:https://www.cnblogs.com/Meiwah/archive/2019/02/22/10416092.html
-Advertisement-
Play Games

在做關於NIO TCP編程小案例時遇到無法監聽write的問題,沒想到只是我的if語句的位置放錯了位置,哎,看了半天沒看出來 貼下課堂筆記: 在Java中使用NIO進行網路TCP套接字編程主要以下幾個類: ServerSocketChannel: 服務端套接字通道,主要監聽接收客戶端請求 Selec ...


在做關於NIO TCP編程小案例時遇到無法監聽write的問題,沒想到只是我的if語句的位置放錯了位置,哎,看了半天沒看出來

貼下課堂筆記

Java中使用NIO進行網路TCP套接字編程主要以下幾個類:

ServerSocketChannel: 服務端套接字通道,主要監聽接收客戶端請求

Selector:通道選擇器,主要用於管理服務端通道和所有客戶端通道(監聽通道中發生的事件),也就說是一個多路通道復用器。

SelectorKey: 事件選擇鍵

SocketChannel: 套接字通道(客戶端)

這篇文章《NIO編程中的SelectionKey.interestOps方法中的邏輯運算》解決了我一些疑問,地址:https://blog.csdn.net/woaiqianzhige/article/details/78696188

NIO 套接字服務端開發步驟:

  1. 創建選擇器
  2. 啟動服務端通道
  3. 設置服務端通道為非阻塞模式
  4. 將服務端通道註冊到選擇器
  5. 輪訓通道事件
  6. 處理通道事件
  7. 關閉通道(可選)

案例:服務端接收客戶端發送的簡訊息,服務端回覆已收到。

服務端代碼:

 

  1 import java.io.IOException;
  2 import java.net.InetSocketAddress;
  3 import java.nio.ByteBuffer;
  4 import java.nio.channels.ClosedChannelException;
  5 import java.nio.channels.SelectionKey;
  6 import java.nio.channels.Selector;
  7 import java.nio.channels.ServerSocketChannel;
  8 import java.nio.channels.SocketChannel;
  9 import java.util.Iterator;
 10 import java.util.Set;
 11 
 12 public class Server {
 13     private Selector selector;
 14     private ServerSocketChannel serverSocketChannel;
 15     private ByteBuffer byteBuffer = ByteBuffer.allocate(8192);
 16 
 17     /**
 18      * 構造方法 啟動伺服器
 19      * 
 20      * @param port
 21      * @throws IOException
 22      */
 23     public Server() {
 24         try {
 25             selector = Selector.open();
 26             serverSocketChannel = ServerSocketChannel.open();
 27             serverSocketChannel.configureBlocking(false);
 28             serverSocketChannel.bind(new InetSocketAddress(10086));
 29             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
 30             System.out.println("Server start successful with port: 10086");
 31         } catch (ClosedChannelException e) {
 32             e.printStackTrace();
 33         } catch (IOException e) {
 34             e.printStackTrace();
 35         }
 36     }
 37 
 38     public static void main(String[] args) throws Exception {
 39         new Server().start();
 40     }
 41 
 42     private void start() {
 43         while (true) {
 44             try {
 45                 selector.select();
 46                 Set<SelectionKey> keys = selector.selectedKeys();
 47                 Iterator<SelectionKey> keyIterator = keys.iterator();
 48                 while (keyIterator.hasNext()) {
 49                     SelectionKey key = keyIterator.next();
 50                     keyIterator.remove();
 51                     if (!key.isValid()) {
 52                         continue;
 53                     }
 54                     if (key.isAcceptable()) {
 55                         accept(key);
 56                     }
 57                     if (key.isReadable()) {
 58                         receive(key);
 59                     }
 60                     if (key.isWritable()) {
 61                         reply(key);
 62                     }
 63                 }
 64             } catch (IOException e) {
 65                 e.printStackTrace();
 66             } catch (Exception e) {
 67                 e.printStackTrace();
 68             }
 69         }
 70     }
 71 
 72     private void reply(SelectionKey key) {
 73         try {
 74             SocketChannel socketChannel = (SocketChannel) key.channel();
 75             byteBuffer.clear();
 76             String message = "receive success";
 77             byteBuffer.put(message.getBytes());
 78             byteBuffer.flip();
 79             socketChannel.write(byteBuffer);
 80             System.out.println("reply:" + message);
 81             byteBuffer.clear();
 82             key.interestOps(SelectionKey.OP_READ);
 83         } catch (IOException e) {
 84             e.printStackTrace();
 85         }
 86     }
 87 
 88     private void receive(SelectionKey key) {
 89         try {
 90             SocketChannel socketChannel = (SocketChannel) key.channel();
 91             byteBuffer.clear();
 92             int flag = socketChannel.read(byteBuffer);
 93             if (flag == -1) {
 94                 key.channel().close();
 95                 key.cancel();
 96                 return;
 97             }
 98             byteBuffer.flip();
 99             byte[] buf = new byte[byteBuffer.remaining()];
100             byteBuffer.get(buf);
101             String message = new String(buf);
102             System.out.println("receive message:" + message);
103             byteBuffer.clear();
104             key.interestOps(SelectionKey.OP_WRITE);
105         } catch (IOException e) {
106             e.printStackTrace();
107         }
108     }
109 
110     private void accept(SelectionKey key) {
111         try {
112             SocketChannel socketChannel = serverSocketChannel.accept();
113             socketChannel.configureBlocking(false);
114             socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
115             System.out.println(Thread.currentThread().getName() + ": create client channel.");
116         } catch (ClosedChannelException e) {
117             e.printStackTrace();
118         } catch (IOException e) {
119             e.printStackTrace();
120         }
121     }
122 }

 

客戶端代碼:

 1 import java.io.IOException;
 2 import java.net.InetSocketAddress;
 3 import java.nio.ByteBuffer;
 4 import java.nio.channels.ClosedChannelException;
 5 import java.nio.channels.SelectionKey;
 6 import java.nio.channels.Selector;
 7 import java.nio.channels.SocketChannel;
 8 import java.util.Iterator;
 9 import java.util.Scanner;
10 
11 public class Client {
12     private Selector selector;
13     private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
14     private SocketChannel socketChannel;
15 
16     public Client() {
17         try {
18             selector = Selector.open();
19             socketChannel = SocketChannel.open();
20             socketChannel.configureBlocking(false);
21             socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
22             socketChannel.connect(new InetSocketAddress("127.0.0.1", 10086));
23             System.out.println("Client start successful");
24         } catch (ClosedChannelException e) {
25             e.printStackTrace();
26         } catch (IOException e) {
27             e.printStackTrace();
28         }
29     }
30 
31     public static void main(String[] args) {
32         new Client().start();    
33     }
34 
35     private void start() {
36         while (true) {
37             try {
38                 selector.select();
39                 Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
40                 while (keys.hasNext()) {
41                     SelectionKey key = keys.next();
42                     keys.remove();
43                     if (!key.isValid()) {
44                         continue;
45                     }
46                     if (key.isConnectable()) {
47                         if (socketChannel.finishConnect()) {
48                             key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT);
49                             System.out.println("Client connect server success");
50                         }
51                     }
52                     if (key.isReadable()) {
53                         receive(key);
54                     }
55                     if (key.isWritable()) {
56                         reply(key);
57                     }
58                 }
59             } catch (Exception e) {
60                 e.printStackTrace();
61             }
62         }
63     }
64 
65     private void reply(SelectionKey key) {
66         try {
67             @SuppressWarnings("resource")
68             Scanner scanner = new Scanner(System.in);
69             byteBuffer.clear();
70             System.out.println("please input message:");
71             String message = scanner.next();
72             byteBuffer.put(message.getBytes());
73             byteBuffer.flip();
74             socketChannel.write(byteBuffer);
75             byteBuffer.clear();
76             System.out.println("send message:" + message);
77             key.interestOps(SelectionKey.OP_READ);
78         } catch (IOException e) {
79             e.printStackTrace();
80         }
81     }
82 
83     private void receive(SelectionKey key) {
84         try {
85             byteBuffer.clear();
86             socketChannel.read(byteBuffer);
87             byteBuffer.flip();
88             byte[] bytes = new byte[byteBuffer.remaining()];
89             byteBuffer.get(bytes);
90             String message = new String(bytes).trim();
91             System.out.println("receive message: " + message);
92             byteBuffer.clear();
93             key.interestOps(SelectionKey.OP_WRITE);
94         } catch (IOException e) {
95             e.printStackTrace();
96         }
97     }
98 }

真是粗心大意了。。。特發此博文給我自己漲漲記性

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 實現效果是在要素點的四周不同位置添加標簽。 此節需要註意一個問題,書寫的先後順序可能會影響運行速度。要註意正確的書寫先後。 1、定義涉及到的所有變數 var minScale = 2500000; var serviceUrl = "https://services.arcgis.com/V6ZHF ...
  • js String擴展方法 'asdasdasd'.repalceA()"AsdAsdAsd" ...
  • 簡介 處理併發問題的重點不在於你的設計是怎樣的,而在於你要評估你的併發,併在併發範圍內處理。你預估你的併發是多少,然後測試r+m是否支持。緩存的目的是為了應對普通對象資料庫的讀寫限制,依托與nosql的優勢進行高速讀寫。 redis本身也有併發瓶頸。所以你要把讀寫和併發區分開來處理。只讀業務是不是可 ...
  • [TOC] JSON Web Token(縮寫 JWT)是目前最流行的跨域認證解決方案,本文介紹它的原理和用法。 一、跨域認證的問題 互聯網服務離不開用戶認證。一般流程是下麵這樣。 1. 用戶向伺服器發送用戶名和密碼。 2. 伺服器驗證通過後,在當前對話(session)裡面保存相關數據,比如用戶角 ...
  • Python環境的安裝 安裝Python: windows: 1、下載安裝包 https://www.python.org/downloads/ 2、安裝 預設安裝路徑:C:\python27 3、配置環境變數 【右鍵電腦】--》【屬性】--》【高級系統設置】--》【高級】--》【環境變數】--》 ...
  • 前言 開心一刻 一名劫匪慌忙中竄上了一輛車的後座,上車後發現主駕和副駕的一男一女疑惑地回頭看著他,他立即拔出槍威脅到:“趕快開車,甩掉後面的警車,否則老子一槍崩了你!”,於是副駕上的男人轉過臉對那女的說:“大姐,別慌,聽我口令把剛纔的動作再練習一遍,掛一檔,輕鬆離合,輕踩油門,走...走,哎 走.. ...
  • 題意 "題目鏈接" 有$n$個位置,每次你需要以$1 \sim n 1$的一個排列的順序去染每一個顏色,第$i$個數可以把$i$和$i+1$位置染成黑色。一個排列的價值為最早把所有位置都染成黑色的次數。問所有排列的分數之和 Sol 神仙題Orz 不難想到我們可以枚舉染色的次數$i \in [\lce ...
  • 《數據結構》這門課程的安排,就要開始各種演算法和數構的燒腦學習了,從最簡單的應用題型入手吧。 本題要求你寫個程式把給定的符號列印成沙漏的形狀。例如給定17個“*”,要求按下列格式列印 所謂“沙漏形狀”,是指每行輸出奇數個符號;各行符號中心對齊;相鄰兩行符號數差2;符號數先從大到小順序遞減到1,再從小到 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...