Java網(wǎng)絡(luò)編程模型(一)

????本系列主要介紹java網(wǎng)絡(luò)編程的模型翁逞,沿著模型的進化線結(jié)合案例分析學(xué)習(xí)砸民。本文主要介紹基于OIO的網(wǎng)絡(luò)編程模型孤个。

基于BIO(OIO)的網(wǎng)絡(luò)編程模型

????BIO(OIO)是指阻塞輸入輸出流(舊輸入輸出流)翁锡,基于阻塞輸入輸出流的網(wǎng)絡(luò)編程初始具有以下特點:
1掐松、服務(wù)端啟動后會阻塞直到監(jiān)測到有客戶端連接众旗;
2罢杉、客戶端發(fā)起連接請求,獲取輸入流讀取數(shù)據(jù)贡歧,如果沒有數(shù)據(jù)可讀取將會一直處于阻塞狀態(tài)滩租;
3、所有連接處理都在一個線程中進行利朵,因此在連接數(shù)較多時律想,連接請求需要排隊等候;

案例——服務(wù)端:

package javanio.oionet;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
 * @author 54353
 * OIO網(wǎng)絡(luò)模型服務(wù)端:
 * 向客戶端寫入服務(wù)端接收時間
 */
public class TestServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket=new ServerSocket(12121)){
            while(true) {//1 循環(huán)等待連接
                //2 accept()阻塞直到有連接進來绍弟,返回對等端socket對象
                Socket client=serverSocket.accept();
                System.out.println("接收到客戶端請求<技础!");
                Writer bWriter=new OutputStreamWriter(client.getOutputStream(),"ASCII");
                Date date=new Date();
                //3 輸出流中寫入時間
                while(true) {//確保任務(wù)不停進行
                    bWriter.write(date.toString()+'\r'+'\n');
                    //4 確保數(shù)據(jù)寫入
                    bWriter.flush();
                    System.out.println("數(shù)據(jù)傳輸完成樟遣!");
                }
            }
        } catch (Exception e) {
            System.out.println("端口可能被占用而叼!");
        }
    }
}

案例——客戶端

package javanio.oionet;

import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestClient2 {

    public static void main(String[] args) {
        Socket socket=null;
        try {
            socket=new Socket("127.0.0.1", 12121);
            InputStreamReader reader=new InputStreamReader(socket.getInputStream(),"ASCII");
            System.out.println("讀取服務(wù)端傳送過來的數(shù)據(jù)!");
            for(int c=reader.read();c!=-1;c=reader.read()) {
                System.out.print((char)c);
            }
        } catch (UnknownHostException e) {
            System.out.println("請求的主機地址不存在豹悬!");
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (socket!=null) {
                try {
                    socket.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

}

????這里客戶端同樣的demo有三個葵陵,啟動服務(wù)端,啟動客戶端后瞻佛,服務(wù)端輸出結(jié)果如下:


server.png

客戶端2輸出結(jié)果如下:


client2.png

客戶端3輸出結(jié)果如下:


client3.png

????TestClient2脱篙,TestClient3啟動后,TestClient2不斷輸出服務(wù)端寫入的時間伤柄,TestClient3卻沒有輸出任何的時間數(shù)據(jù)绊困。這是因為所有客戶端連接共享一個服務(wù)端線程,服務(wù)端在不斷向TestClient2輸出數(shù)據(jù)适刀,TestClient3必須等到TestClient2的請求結(jié)束秤朗,服務(wù)端向其輸出數(shù)據(jù)后才能輸出時間數(shù)據(jù)。這也是本文一開始提到的第三個特點蔗彤。
針對這種模式存在的缺陷川梅,基于OIO提出了多線程的模型,也即是服務(wù)端針對每一個請求開啟一個新的線程去處理數(shù)據(jù):
服務(wù)端的改進:

package javanio.oionet;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
 * @author 54353
 * OIO網(wǎng)絡(luò)模型服務(wù)端:
 * 向客戶端寫入服務(wù)端接收時間
 */
public class TestServer2 {
    
     static class  Task implements Runnable{
          private Socket client;
          public Task(Socket client) {
            this.client=client;
            }
        @Override
        public void run() {
            System.out.println("接收到客戶端請求H欢簟贫途!");
            Writer bWriter;
            try {
                bWriter = new OutputStreamWriter(client.getOutputStream(),"ASCII");
                Date date=new Date();
                //4 輸出流中寫入時間
                while(true) {//任務(wù)不斷進行
                    bWriter.write(date.toString()+'\r'+'\n');
                    //5 確保數(shù)據(jù)寫入
                    bWriter.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
        }
         
     }

    public static void main(String[] args) {
        try (ServerSocket serverSocket=new ServerSocket(12122)){
            while(true) {//1 循環(huán)等待連接
                //2 accept()阻塞直到有連接進來,返回對等端socket對象
                Socket client=serverSocket.accept();
                //3 一旦有連接進來待侵,開啟新的線程處理連接
                new Thread(new Task(client)).start();
            }
        } catch (Exception e) {
            System.out.println("端口可能被占用丢早!");
        }
    }

}

????在運用多線程處理連接后,輸出結(jié)果下:
服務(wù)端輸出


server2.png

幾個客戶端輸出結(jié)果相同


client2.png

client3.png

????由此可見,運用多線程OIO模型可以解決怨酝,多請求同時發(fā)生時的排隊等候問題傀缩,可以帶來更好的客戶體驗。但是如果線程數(shù)過多农猬,對內(nèi)存的消耗大赡艰,同時線程數(shù)過多,線程輪轉(zhuǎn)帶來的消耗也會非常大斤葱,因此肆無忌憚的使用多線程去處理并發(fā)請求問題只能算是一種蠻干慷垮,對于高并發(fā)場景,更是會帶來災(zāi)難性危害揍堕。

關(guān)于Reactor模式

????Reactor模式也即響應(yīng)模式料身,就本文所涉及的網(wǎng)絡(luò)編程而言,只有獲取到客戶端的連接請求后衩茸,服務(wù)端才執(zhí)行后續(xù)的程序芹血。對于OIO阻塞輸入輸出流,顯然還存在一個明顯缺陷:如果一直未接收到客戶端請求楞慈,服務(wù)端一直處于阻塞狀態(tài)幔烛,后面與接入無關(guān)的代碼也需要等待,這顯然會浪費很多的CPU時間抖部,因此從這點考慮说贝,多線程的OIO模式仍存在進步空間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慎颗,一起剝皮案震驚了整個濱河市乡恕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俯萎,老刑警劉巖傲宜,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夫啊,居然都是意外死亡函卒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門撇眯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來报嵌,“玉大人,你說我怎么就攤上這事熊榛∶” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵玄坦,是天一觀的道長血筑。 經(jīng)常有香客問我绘沉,道長,這世上最難降的妖魔是什么豺总? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任车伞,我火速辦了婚禮,結(jié)果婚禮上喻喳,老公的妹妹穿的比我還像新娘另玖。我一直安慰自己,他們只是感情好沸枯,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布日矫。 她就那樣靜靜地躺著赂弓,像睡著了一般绑榴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盈魁,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天翔怎,我揣著相機與錄音,去河邊找鬼杨耙。 笑死赤套,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的珊膜。 我是一名探鬼主播容握,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼车柠!你這毒婦竟也來了剔氏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤竹祷,失蹤者是張志新(化名)和其女友劉穎谈跛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塑陵,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡感憾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了令花。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阻桅。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兼都,靈堂內(nèi)的尸體忽然破棺而出嫂沉,到底是詐尸還是另有隱情,我是刑警寧澤俯抖,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布输瓜,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏尤揣。R本人自食惡果不足惜搔啊,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望北戏。 院中可真熱鬧负芋,春花似錦、人聲如沸嗜愈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蠕嫁。三九已至锨天,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剃毒,已是汗流浹背病袄。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赘阀,地道東北人益缠。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像基公,于是被迫代替她去往敵國和親幅慌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 計算機網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實質(zhì)就是兩個(或多個)設(shè)備(例如計算機)之間的數(shù)據(jù)傳輸轰豆。 按照計算機網(wǎng)絡(luò)的定義胰伍,通過一定...
    蛋炒飯_By閱讀 1,231評論 0 10
  • 在一個方法內(nèi)部定義的變量都存儲在棧中,當(dāng)這個函數(shù)運行結(jié)束后秒咨,其對應(yīng)的棧就會被回收喇辽,此時,在其方法體中定義的變量將不...
    Y了個J閱讀 4,420評論 1 14
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,111評論 1 32
  • “主上雨席,這是暗隱樓送來的新一批暗衛(wèi)菩咨,主人看有要留下的嗎《咐澹”慕雨跪地向著一位一身深藍色衣服正在研究棋盤的青年道抽米。 慕...
    9daf83399845閱讀 28,460評論 0 0
  • 高難度談話讀后感 之前兩個晚上讀了一遍《高難度談話》,但并沒有認真去讀去思考糙置,這次打算仔細閱讀云茸,并加上自己或者別人...
    Asensios閱讀 156評論 0 0