Java-網(wǎng)絡(luò)(一)

網(wǎng)絡(luò)編程分為服務(wù)端和客戶(hù)端。服務(wù)端就相當(dāng)于我們平時(shí)說(shuō)的服務(wù)器斟叼,有固定的IP地址踱葛,隨時(shí)等待服務(wù)器連接并做出響應(yīng)丹莲;而客戶(hù)端相當(dāng)于各種端系統(tǒng),找到服務(wù)端進(jìn)行連接獲取服務(wù)尸诽。
IP地址:唯一標(biāo)識(shí)某一臺(tái)電腦
端口號(hào):唯一表示一臺(tái)電腦上的某一個(gè)進(jìn)程
網(wǎng)絡(luò)通信都是使用Socket來(lái)實(shí)現(xiàn)
創(chuàng)建一個(gè)客戶(hù)端的Socket服務(wù)甥材,在該對(duì)象建立時(shí)就可去連接指定主機(jī),因?yàn)門(mén)CP是面向連接的性含,所以在建立Socket服務(wù)時(shí)洲赵,就要有服務(wù)端存在,并連接成功,形成通路后叠萍,再通過(guò)該通道進(jìn)行數(shù)據(jù)的傳輸芝发。

下面寫(xiě)幾個(gè)簡(jiǎn)單的Demo

一.實(shí)現(xiàn)客戶(hù)端向服務(wù)端傳遞數(shù)據(jù)功能

我們先寫(xiě)客戶(hù)端

class Client{
    public static void main(String[] args) throws IOException{
        //1.創(chuàng)建用于通信的socket
        // 指明和誰(shuí)通信:ip地址 端口號(hào)
        Socket socket = new Socket("10.129.25.58",8989);
        // 接收服務(wù)器端的數(shù)據(jù)
       BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        // 向服務(wù)器端發(fā)送數(shù)據(jù)
        //socket.getOutputStream();

        //讀取服務(wù)器端發(fā)來(lái)的數(shù)據(jù)
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }

        //客戶(hù)端向服務(wù)器端發(fā)送數(shù)據(jù)
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("你好啊");
        socket.shutdownOutput();
    }
}

這里再簡(jiǎn)單提一下:
(1)字節(jié)操作流:OutputStream、InputStream苛谷;
(2)字符操作流:Writer辅鲸、Reader。

BufferedReader 由Reader類(lèi)擴(kuò)展而來(lái)抄腔,提供通用的緩沖方式文本讀取瓢湃,readLine讀取一個(gè)文本行,
從字符輸入流中讀取文本赫蛇,緩沖各個(gè)字符绵患,從而提供字符、數(shù)組和行的高效讀取悟耘。

BufferedWriter 由Writer 類(lèi)擴(kuò)展而來(lái)落蝙,提供通用的緩沖方式文本寫(xiě)入, newLine使用平臺(tái)自己的行分隔符暂幼,將文本寫(xiě)入字符輸出流筏勒,緩沖各個(gè)字符,從而提供單個(gè)字符旺嬉、數(shù)組和字符串的高效寫(xiě)入管行。

OutputStreamWriter:是Writer的子類(lèi),將輸出的字符流變?yōu)樽止?jié)流邪媳,即將一個(gè)字符流的輸出對(duì)象變?yōu)樽止?jié)流輸出對(duì)象捐顷。

InputStreamReader:是Reader的子類(lèi),將輸入的字節(jié)流變?yōu)樽址饔晷В磳⒁粋€(gè)字節(jié)流的輸入對(duì)象變?yōu)樽址鞯妮斎雽?duì)象迅涮。

以文件操作為例,內(nèi)存中的字符數(shù)據(jù)需要通過(guò)OutputStreamWriter變?yōu)樽止?jié)流才能保存在文件中徽龟,讀取時(shí)需要將讀入的字節(jié)流通過(guò)InputStreamReader變?yōu)樽址?/p>

然后再寫(xiě)服務(wù)器

class Server{
    public static void main(String[] args) throws IOException{
        //1.創(chuàng)建服務(wù)器端的ServerSocket
        ServerSocket ss = new ServerSocket(8989);

        //2.獲取連接的客戶(hù)端的socket
        Socket clientSocket = ss.accept();

        //3.向客戶(hù)端發(fā)送數(shù)據(jù)
        //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

        PrintStream ps = new PrintStream(clientSocket.getOutputStream());
        ps.println("登陸成功");

        //輸出完畢
        clientSocket.shutdownOutput();

        //4.接收客戶(hù)端發(fā)來(lái)的數(shù)據(jù)
        BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }
}

接下來(lái)我們?cè)倏匆幌逻\(yùn)行結(jié)果:
注意:先運(yùn)行服務(wù)器叮姑,再運(yùn)行客戶(hù)端

08221.png

客戶(hù)端顯示了登錄成功
然后我們?cè)倏匆幌路?wù)器


08222.png

上面這個(gè)Demo是很基礎(chǔ)的,所以在這個(gè)基礎(chǔ)上再加一丟丟難度据悔,也就是

二.實(shí)現(xiàn)服務(wù)器給客戶(hù)端發(fā)任意消息

class MyClient{
    public static void main(String[] args){
        //連接服務(wù)器端的socket
        Socket socket = null;
        try {
            socket = new Socket("10.129.36.120",8080);

            //接收服務(wù)器端信息
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }  

            //從鍵盤(pán)輸入數(shù)據(jù) 發(fā)送給服務(wù)器端
        }catch (IOException e){
            System.out.println("網(wǎng)絡(luò)出錯(cuò)传透,請(qǐng)重新登陸");
        }finally {
            //關(guān)閉連接
            try {
                socket.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

class MyServer{
    public static void main(String[] args){
        //創(chuàng)建ServerSocket
        try(ServerSocket ss = new ServerSocket(8080)) {
            //監(jiān)聽(tīng)客戶(hù)端的連接
            Socket socket = ss.accept();

            //從終端接收數(shù)據(jù)
            BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));

            //獲取向客戶(hù)輸出數(shù)據(jù)的輸出流
            PrintStream ps = new PrintStream(socket.getOutputStream());
            String line = null;

            while ((line = keyin.readLine()) != null){
                //發(fā)送給客戶(hù)端
                ps.println(line);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

這時(shí)候我們運(yùn)行一下看結(jié)果

運(yùn)行一開(kāi)始 兩邊
[圖片上傳中...(08224.png-3be875-1566472778836-0)]
08224.png

我們會(huì)看到兩邊都是空的 然后這時(shí)候我們?cè)诜?wù)器輸入想發(fā)送的內(nèi)容

08225.png

輸入完內(nèi)容后記得要敲一下回車(chē)鍵
然后再看客戶(hù)端
08226.png

ok內(nèi)容收到,功能實(shí)現(xiàn)屠尊。

我們做到了實(shí)現(xiàn)發(fā)消息旷祸,這時(shí)候會(huì)想怎么做一個(gè)能夠發(fā)圖片的,所以接下來(lái)我們?cè)僮鲆粋€(gè)實(shí)現(xiàn)給

二.服務(wù)器端發(fā)送圖片

class Client {
    public static void main(String[] args) throws IOException {
        //連接服務(wù)器 獲取socket
        Socket socket = new Socket("10.129.36.120", 8080);

        //創(chuàng)建服務(wù)器端對(duì)應(yīng)的輸入流 用于接收服務(wù)器端發(fā)來(lái)的數(shù)據(jù)
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println(br.readLine());

        //向服務(wù)器端發(fā)送文件(圖片)
        //1.將文件寫(xiě)入到內(nèi)存里
        String path = "C:\\Users\\hp\\Desktop\\1.JPG";
        FileInputStream fis = new FileInputStream(path);

        //2.創(chuàng)建字節(jié)流 OutputStream
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        byte[] buf = new byte[1024];
        int len = -1;
        while ((len = fis.read(buf)) != -1) {
            bos.write(buf, 0, len);
        }
        socket.shutdownOutput();
    }
}


class Server {
    public static void main(String[] args) throws IOException {
        //創(chuàng)建服務(wù)器端的ServerSocket
        ServerSocket ss = new ServerSocket(8080);

        //監(jiān)聽(tīng)客戶(hù)端連接
        //當(dāng)有客戶(hù)端來(lái)連接這個(gè)服務(wù)器 就可以得到對(duì)應(yīng)的socket
        //當(dāng)沒(méi)有客戶(hù)端來(lái)連接 服務(wù)器一直在這里等待
        Socket socket = ss.accept();

        //創(chuàng)建客戶(hù)端對(duì)應(yīng)的輸出流 用于向這個(gè)客戶(hù)端發(fā)送數(shù)據(jù)
        PrintStream ps = new PrintStream(socket.getOutputStream());
        ps.println("連接成功 可以向我發(fā)數(shù)據(jù)了!");

        //接收客戶(hù)端傳遞過(guò)來(lái)的圖片
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        //文件對(duì)應(yīng)的輸出流
        String path = "E:\\Java89\\app\\src\\main\\java\\java08212\\2.JPG";
        FileOutputStream fos = new FileOutputStream(path);

        byte[] buf = new byte[1024];
        int len = -1;
        while ((len = bis.read(buf)) != -1){
            fos.write(buf,0,len);
        }
    }
}

接下來(lái)開(kāi)始運(yùn)行程序:
當(dāng)客戶(hù)端連接到服務(wù)器時(shí)讼昆,客戶(hù)端會(huì)收到一段提示:


然后服務(wù)器指定的位置會(huì)收到一張圖片:


08228.png

圖片也發(fā)送成功了
最后我們?cè)賹?shí)現(xiàn)一個(gè)托享,兩人之間簡(jiǎn)單的聊天功能骚烧,上面我們做的都是單向的,客戶(hù)端向服務(wù)器發(fā)送消息闰围、圖片赃绊,所以我們要再實(shí)現(xiàn)

四.兩人之間互發(fā)消息

class Client{
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("10.129.36.120", 8080);

        //用一個(gè)子線(xiàn)程處理服務(wù)器端數(shù)據(jù)
         new Thread(new ClientThread(socket)).start();

        //主線(xiàn)程處理終端輸入 發(fā)送給服務(wù)器端
        BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        String line = null;

        while ((line = keyin.readLine()) != null) {
            ps.println(line);
        }
    }
}

/**
 * 創(chuàng)建一個(gè)子線(xiàn)程處理客戶(hù)端接收服務(wù)器端數(shù)據(jù)
 */

class ClientThread implements Runnable{
    private Socket socket;

    //保存操作socket對(duì)象
     public ClientThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        BufferedReader br = null;
        try {
            //獲取服務(wù)器端的輸入流對(duì)象
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            //讀取數(shù)據(jù)
            String line = null;
            while ((line = br.readLine()) != null){
                 System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("網(wǎng)絡(luò)出錯(cuò) 請(qǐng)重新登錄");
            System.exit(-1);
        }finally {
            try {
                if(br != null){
                    br.close();
                }
                if (socket != null){
                    socket.close();
                }
            }catch (IOException ex){

            }
        }
    }
}
class Server{
    public static void main(String[] args) throws IOException{
        ServerSocket ss = new ServerSocket(8080);
        //獲取客戶(hù)端的socket
        Socket socket = ss.accept();

        new ServerThread(socket).start();

        //終端輸入流對(duì)象
        BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
        //客戶(hù)端的輸出流對(duì)象
        PrintStream ps = new PrintStream(socket.getOutputStream());
        //讀取終端的輸入 將輸入輸出給客戶(hù)端
        String line = null;
        while ((line = keyin.readLine()) != null){
            ps.println(line);
        }
    }
}
/**
 * 創(chuàng)建一個(gè)子線(xiàn)程處理服務(wù)器端接收客戶(hù)端的數(shù)據(jù)
 */

class ServerThread extends Thread{
    private Socket socket;
    public ServerThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            System.out.println("網(wǎng)絡(luò)異常 請(qǐng)重新登錄");
            System.exit(-1);
        }finally {
            //關(guān)閉輸入輸出流
            //關(guān)閉對(duì)應(yīng)的socket連接
            try {
                if (br != null){
                    br.close();
                }
                if (socket != null){
                    socket.close();
                }
            }catch (IOException e){

            }
        }
    }
}

運(yùn)行結(jié)果:


08229.png

082210.png

兩個(gè)人之間的簡(jiǎn)單的聊天功能已經(jīng)實(shí)現(xiàn)
那么,如何實(shí)現(xiàn)群聊功能呢羡榴?請(qǐng)看下回分解.....

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碧查,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子校仑,更是在濱河造成了極大的恐慌忠售,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迄沫,死亡現(xiàn)場(chǎng)離奇詭異稻扬,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)羊瘩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)泰佳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人尘吗,你說(shuō)我怎么就攤上這事逝她。” “怎么了睬捶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵黔宛,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我擒贸,道長(zhǎng)宁昭,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任酗宋,我火速辦了婚禮,結(jié)果婚禮上疆拘,老公的妹妹穿的比我還像新娘蜕猫。我一直安慰自己,他們只是感情好哎迄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布回右。 她就那樣靜靜地躺著,像睡著了一般漱挚。 火紅的嫁衣襯著肌膚如雪翔烁。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天旨涝,我揣著相機(jī)與錄音蹬屹,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛慨默,可吹牛的內(nèi)容都是我干的贩耐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼厦取,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼潮太!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起虾攻,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铡买,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后霎箍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奇钞,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年朋沮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛇券。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡樊拓,死狀恐怖纠亚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情筋夏,我是刑警寧澤蒂胞,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站条篷,受9級(jí)特大地震影響骗随,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赴叹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一鸿染、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乞巧,春花似錦涨椒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至是辕,卻和暖如春囤热,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背获三。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工旁蔼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锨苏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓牌芋,卻偏偏與公主長(zhǎng)得像蚓炬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子躺屁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸肯夏。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義,通過(guò)一定...
    蛋炒飯_By閱讀 1,224評(píng)論 0 10
  • 概要 64學(xué)時(shí) 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,196評(píng)論 0 3
  • Java知識(shí)點(diǎn)1犀暑、==和equals的區(qū)別基本類(lèi)型比較==比較內(nèi)容 equals比較地址值引用類(lèi)型比較==比較地址...
    壓抑的內(nèi)心閱讀 592評(píng)論 0 0
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,101評(píng)論 1 32
  • 語(yǔ)言表達(dá)能力太差驯击,直接導(dǎo)致別人想騎到我頭上拉屎,這怪我耐亏,草泥馬徊都,你欺軟怕硬更無(wú)恥
    可兒可兒閱讀 70評(píng)論 0 0