前幾天我們公司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實現非阻塞服務端的示意圖:
具體實現可以看以下的例項服務端:
客戶端可以用tcp/ip 測試工具 測試。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)
}}
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時間。每個執行緒遇到外部為準備好的時候,都會阻塞掉。阻塞...