Java 非阻塞 socket 通訊

2021-06-08 12:26:37 字數 1337 閱讀 8152

前幾天我們公司c語言組的人需要乙個基於socket的報文接收器來方便他們測試專案,我花了小半天給他們做了個多執行緒的socket服務端,我寫好後在本機上測試後交給了他們,但是他們那邊能連上伺服器端,但是傳送訊息時沒響應,後來我看到他們用的都是tcp/ip測試工具(乙個c/s結構的socket除錯工具)來測了,傳送時我的後台也沒有收到請求報文,但是他們的連線斷了之後 我這邊就收到了,又谷歌了一下,還真發現了問題,因為我的服務端 用的是serversocket類 這種是阻塞式的socket 當連線之後服務端就一直在讀取流或者寫出流 到快取中,這種情況有兩種方法解決,一是在客戶端傳送報文時末尾加個換行符,這種方法後來我試了下 好像是可以 但是客戶端還是收不到實時的響應。第二種方法就是運用nio包下的非阻塞式的socket了(這種方法是最優的)。

非阻塞式socket 運用到了以下幾個重要概念:

selector:是 乙個selectablechannel物件的多路復用器,所有非阻塞式的channel都要註冊到這個selector上。

serversocketchannel:對應的是serversocket

socketchannel:對應的是socket

selectionkey:這個就是來描述channel與selector之間註冊關係的乙個對映物件。

bytebuffer:說這個首先要說一下channel與流的區別了,以前我們用的socket,讀取寫入資料用的都是流的形式,而nio包下的採用的都是塊的形式,channel可以把一塊資料對映到記憶體上,這樣的話處理速度上記憶體速度肯定是優於流的,其實有點像作業系統的虛擬記憶體和分頁儲存。而bytebuffer就是channel的乙個容器,用來讀和寫資料用的,channel也只能通過bytebuffer來處理資料。

如圖所示是用nio實現非阻塞服務端的示意圖:

具體實現可以看以下的例項服務端:

public class nserver 

if(sk.isreadable())

} catch (exception e)

if(content.length()>0)

//為讀取資料做準備

buffer.clear();

}if(sk.isvalid()&&sk.iswritable())

//去除已經處理過的key

it.remove();

}} }

public static void main(string args) catch (ioexception e)

}}

客戶端可以用tcp/ip 測試工具 測試。

socket非阻塞通訊

fd 非阻塞需要多執行緒程式設計 服務端方式1 使用threading庫實現多執行緒 基本方法和單程序基本寫法一致,將收發部分封裝為函式以便開啟其他執行緒 import socket import time import threading defhandle socket conn,addr wh...

NIO實現非阻塞式Socket通訊

filechannel 由上圖可知道,該channel 只有阻塞模式。datagramchannel socketchannel serversocketchannel 三個網路channel 可以通過configureblocking 方法,設定非阻塞模式 nio 只有在 網路中,使用select...

socket阻塞與非阻塞

何為阻塞?在以上過程中若連線還沒到來,那麼接受阻塞,程式執行到這裡不得不掛起,cpu轉而執行其他執行緒。在以上過程中若資料還沒準備好,請閱讀會一樣也會阻塞。阻塞式網路io的特點 多執行緒處理多個連線。每個執行緒擁有自己的棧空間並且占用一些cpu時間。每個執行緒遇到外部為準備好的時候,都會阻塞掉。阻塞...