JAVA-7NIO之Socket/ServerSocket Channel

来源:http://www.cnblogs.com/zhangxinly/archive/2017/06/12/6993970.html
-Advertisement-
Play Games

一、ServerSocketChannel Java NIO中的 ServerSocketChannel 是一個可以監聽新進來的TCP連接的通道, 就像標準IO中的ServerSocket一樣。ServerSocketChannel類在 java.nio.channels包中。 打開 ServerS ...


一、ServerSocketChannel

Java NIO中的 ServerSocketChannel 是一個可以監聽新進來的TCP連接的通道, 就像標準IO中的ServerSocket一樣。ServerSocketChannel類在 java.nio.channels包中。

打開 ServerSocketChannel

通過調用 ServerSocketChannel.open() 方法來打開ServerSocketChannel.

關閉 ServerSocketChannel

通過調用ServerSocketChannel.close() 方法來關閉ServerSocketChannel. 

監聽新進來的連接

通過 ServerSocketChannel.accept() 方法監聽新進來的連接。當 accept()方法返回的時候,它返回一個包含新進來的連接的 SocketChannel。因此, accept()方法會一直阻塞到有新連接到達。

通常不會僅僅只監聽一個連接,在while迴圈中調用 accept()方法. 

當然,也可以在while迴圈中使用除了true以外的其它退出準則。

非阻塞模式

ServerSocketChannel可以設置成非阻塞模式。在非阻塞模式下,accept() 方法會立刻返回,如果還沒有新進來的連接,返回的將是null。 因此,需要檢查返回的SocketChannel是否是null.如:

    /**
     * socket server channel
     */
    @Test
    public void text2() throws IOException {
        ServerSocketChannel channel = ServerSocketChannel.open();    //新建channel
        channel.socket().bind(new InetSocketAddress(9999));     //監聽埠
        channel.configureBlocking(true);                             //設置阻塞

        while (true) {
            SocketChannel accept = channel.accept();                    //設置為阻塞,則此方法阻塞,直到有連接
            //如果設置為非阻塞,需要在這裡判斷 accept == null?
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            accept.read(byteBuffer);
            byteBuffer.flip();                                    //反轉
            while (byteBuffer.hasRemaining()) {                   //判斷
                System.err.println((char)byteBuffer.get());       //輸出
            }
        }
    }

 

二、SocketChannel

Java NIO中的SocketChannel是一個連接到TCP網路套接字的通道。可以通過以下2種方式創建SocketChannel:

  1. 打開一個SocketChannel並連接到互聯網上的某台伺服器。
  2. 一個新連接到達ServerSocketChannel時,會創建一個SocketChannel。

打開 SocketChannel

下麵是SocketChannel的打開方式:

關閉 SocketChannel

當用完SocketChannel之後調用SocketChannel.close()關閉SocketChannel:

從 SocketChannel 讀取數據

要從SocketChannel中讀取數據,調用一個read()的方法之一。

首先,分配一個Buffer。從SocketChannel讀取到的數據將會放到這個Buffer中。

然後,調用SocketChannel.read()。該方法將數據從SocketChannel 讀到Buffer中。read()方法返回的int值表示讀了多少位元組進Buffer里。如果返回的是-1,表示已經讀到了流的末尾(連接關閉了)。

寫入 SocketChannel

寫數據到SocketChannel用的是SocketChannel.write()方法,該方法以一個Buffer作為參數。

註意SocketChannel.write()方法的調用是在一個while迴圈中的。Write()方法無法保證能寫多少位元組到SocketChannel。所以,我們重覆調用write()直到Buffer沒有要寫的位元組為止。

非阻塞模式

可以設置 SocketChannel 為非阻塞模式(non-blocking mode).設置之後,就可以在非同步模式下調用connect(), read() 和write()了。

connect()

如果SocketChannel在非阻塞模式下,此時調用connect(),該方法可能在連接建立之前就返回了。為了確定連接是否建立,可以調用finishConnect()的方法。

 

write()

非阻塞模式下,write()方法在尚未寫出任何內容時可能就返回了。所以需要在迴圈中調用write()。前面已經有例子了,這裡就不贅述了。

read()

非阻塞模式下,read()方法在尚未讀取到任何數據時可能就返回了。所以需要關註它的int返回值,它會告訴你讀取了多少位元組。

非阻塞模式與選擇器

非阻塞模式與選擇器搭配會工作的更好,通過將一或多個SocketChannel註冊到Selector,可以詢問選擇器哪個通道已經準備好了讀取,寫入等。Selector與SocketChannel的搭配使用會在後面詳講。

/**
     * socket channel
     */
    @Test
    public void test3() throws IOException {
        SocketChannel channel = SocketChannel.open();                               //新建服務端
        channel.connect(new InetSocketAddress("127.0.0.1",9999));   //連接服務端地址
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);  //緩衝區
        byteBuffer.put("123".getBytes());
        byteBuffer.flip();                                  //反轉
        while (byteBuffer.hasRemaining()) {                 //判斷
            channel.write(byteBuffer);
        }
    }

 


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

-Advertisement-
Play Games
更多相關文章
  • 基本語法 shell的if語法和C語言等高級語言非常相似,唯一需要註意的地方就是shell的if語句對空格方面的要求比較嚴格(其實shell對所有語法的空格使用都比較嚴格),如果在需要空格的地方沒有打上空格,都會報錯。如if [ $1x == "ip"x ];then echo "abc";fi中少 ...
  • 今天上午找資料,發現了mongodb,閑來無事就研究了下,本人用的是phpstudy集成包添加mongodb擴展。 1.添加mongo、mongodb擴展 phpstudy集成環境一般用的是32位php,去官網下載32位的mongo、mongodb擴展 mongo:http://pecl.php.n ...
  • 期末複習比較忙過段時間來專門寫scrapy框架使用,今天介紹如何用python生成詞雲,雖然網上有很多詞雲生成工具,不過自己用python來寫是不是更有成就感。 今天要生成的是勵志歌曲的詞雲,百度文庫裡面找了20來首,如《倔強》,海闊天空是,什麼的大家熟悉的。 所要用到的python庫有 jieba ...
  • 鍵盤錄入(Java): 1.導包 格式 import java.util.Scanner; 位置 在class上面 2.創建鍵盤錄入對象 格式 Scanner sc = new Scanner(System.in); 3.通過對象獲取數據 格式 int x = sc.nextInt(); impor ...
  • 最近看了看JavaWeb的書籍,才感覺到大二時候學的JavaWeb才僅僅只是個入門。最尷尬的當初還沒咋學一直在看.NET,現在看起來JavaWeb,各種框架各種頭疼啊。看了幾個例子之後覺得,還是自己動手做個項目試試。邊做邊學才能學的快一點。做的時候用博客園記錄下過程,省得以後忘。之所以選圖書館管理系 ...
  • 本文是作者在學習了軟體工程(C編碼實踐篇)課程後的學習總結性質的文章 希望能通過自己的一些理解和經驗幫助大家更好地理解軟體工程的有關內容。。 學生 戢祥 課程地址《軟體工程(C編碼實踐篇)》MOOC課程http://mooc.study.163.com/course/USTC-1000002006 ...
  • 為瞭解決用一個命令(巨集)給方法,類,js方法添加註釋,經過幾天的研究.終於得到結果了. 實現的效果如下: 給Java中的method添加方法: 給 Java class 添加註釋: 給js 的方法添加註釋 現在把答案公佈如下 Abbreviation: Template text(註1): Edit ...
  • python ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...