首先我們先來看socketserver這個的實現類,這個類雖然實現的很簡單,但是包含了nio請求的最基本的過程。
這個類實現的比較經典
我們先來看下區域性變數:
// 從類的命名來看是乙個requesthandler的工程類
private final requesthandle***ctory handle***ctory;
// 可以接受的最大請求數
private final int maxrequestsize ;
// 任務處理者的數量
private final processor processors ;
// 封裝的acceptor
private final acceptor acceptor ;
// socketserver的統計類
private final socketserverstats stats ;
// server的配置類
private final serverconfig serverconfig ;
接著我們來看下建構函式和startup函式
public socketserver(requesthandle***ctory handle***ctory, //
serverconfig serverconfig)
/*** start the socket server and waiting for finished
** @throws interruptedexception
*/public void startup() throws interruptedexception
utils. newthread("jafka-acceptor", acceptor, false).start();
acceptor.awaitstartup();
}
我們接下來來看acceptor的實現類。
在看之前,我們先來了解下
abstractserverthread這個類,這個是伺服器端所有執行緒的父類,裡面包含乙個selector。
acceptor類是乙個執行緒類,我們還是先來看下它的區域性變數。
// 繫結的埠
private int port ;
// 一批任務處理器
private processor processors;
// send和recivebuffer的大小
private int sendbuffersize ;
private int receivebuffersize ;
既然是執行緒類,我們接著來看run方法。
1. run方法的開頭進行了socket的繫結。
// 初始化serversocket,以非阻塞的方式啟動,並經accept事件註冊到selector,
// 這樣就可以處理accept事件了
final serversocketchannel serverchannel;
try catch (ioexception e)
2. 第二部分是socket繫結完畢後,通知server啟動成功
3. 從selector裡面select出來乙個請求,然後選擇乙個processor進行處理,我們簡單來看**
//
int currentprocessor = 0;
while(isrunning()) catch (ioexception e)
if(ready<=0)continue;
iteratoriter = getselector().selectedkeys().iterator();
while(iter.hasnext() && isrunning())
try else
// 選擇下乙個processor
currentprocessor = (currentprocessor + 1) % processors .length ;
} catch (throwable t)
}
4. 當server退出後關閉server和selector
最後我們來看下accept私有函式的實現:
其實非常簡單,將請求交個processor進行處理
private void accept(selectionkey key, processor processor) throws ioexception
接下來我們接著來看processor類的實現。
processor我們先來看下accept函式
public void accept(socketchannel socketchannel)
這個地方為什麼要呼叫wakeup,我們目前還沒有想到,還在繼續思考
下來我們來看最主要的run函式:
public void run() else if (key.iswritable()) else if (!key.isvalid()) else
// 如果傳送讀操作的異常
} catch (eofexception eofe) catch (invalidrequestexception ire) catch (throwable t) else
close(key);}}
} catch (ioexception e) }//
logger.info("closing selector while shutting down");
closeselector();
shutdowncomplete();
}
1. 通知processor啟動成功,這個裡面我們也看到,程式中都散落這一些countdownlatch
2. 將新來的請求的read事件註冊到channel上
3. 從selector裡面選擇read和write事件,然後分別呼叫read和write函式
我們重點來看下read函式的實現:
private void read(selectionkey key) throws ioexception else
int read = request.readfrom(socketchannel);
stats.recordbytesread(read);
if (read < 0) else if (request.complete())
} else
}}
我們接著來看handle函式
/**
* handle a completed request producing an optional response
*/private send handle(selectionkey key, receive request)
string logformat = "handling %s request from %s";
requestlogger.trace(format(logformat, requesttype, channelfor(key).socket().getremotesocketaddress()));
}// 從reqeusthandler工廠裡面取得requesthandler
throw new invalidrequestexception("no handler found for request");
}// 呼叫handler將結果返回
long start = system.nanotime();
stats.recordrequest(requesttype, system.nanotime() - start);
return maybesend;
}
我們也看下write函式,堪稱比較經典的實現
private void write(selectionkey key) throws ioexception else
}
python學習之網路
1 udp網路程式傳送流程 import socket def main 1 建立socket物件 udp socket socket.socket socket.af inet,socket.sock dgram 2 socket收發資料 發資料.注sendto b 內容 用元組形式寫ip和埠號 ...
Linux學習之網路基礎
一 ios osi七層協議介紹 二 網路基礎介紹 1 ip分為五大類,如上圖。在給某個網路分配乙個ip 外網ip 位址時,可以通過該位址進行網路連線。同樣若是這個ip屬於某個團體,如學校等。那麼可以通過該ip所在的類 所在網段 給學校的班級學生每個人的電腦分配乙個私有ip 私有ip號如上 此時所有的...
網路學習之eNSP使用
組網 網路組建 學習ensp主要是為了擁有一定的網路組建能力,看得懂網路拓撲圖,自己能夠繪製,並且對常見的網路裝置有一定的了解,可以進行一些安全配置等。下面介紹ensp ensp enterprise network simulation platform 是一款由華為提供的免費的 可擴充套件的 圖...