国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java中Nio編程實(shí)現(xiàn)網(wǎng)絡(luò)編程的多客戶端與服務(wù)器連接完整步驟

不知名網(wǎng)友 / 2559人閱讀

摘要:編程核心是通道和選擇器,選擇器通過不斷輪詢,執(zhí)行對(duì)應(yīng)的函數(shù)。所以我們需要捕獲這個(gè)異常,并且開始不斷重連。如果客戶端關(guān)閉那么服務(wù)器也要主動(dòng)關(guān)閉他數(shù)據(jù)庫代碼及實(shí)體類如果還想實(shí)現(xiàn)數(shù)據(jù)庫方面代碼,私我

前言:

物聯(lián)網(wǎng)答辯終于結(jié)束了 記一下自己網(wǎng)絡(luò)編程的代碼 重連代碼寫了好久 try catch原來可以這么用!

學(xué)習(xí)地址:https://www.bilibili.com/video/BV1gz4y1C7RK

項(xiàng)目結(jié)構(gòu):

1、服務(wù)器代碼:

package Server;import Entiles.User;import Utils.JdbcUtil;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.nio.charset.Charset;import java.text.SimpleDateFormat;import java.util.Iterator;import java.util.Scanner;import java.util.Set;public class ChatServer {    public void StratServer(int port) throws IOException {        //soket通道 客戶通道        //創(chuàng)建服務(wù)端通道        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();        //非堵塞模式        serverSocketChannel.configureBlocking(false);        //創(chuàng)建buffer        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);        //綁定端口        serverSocketChannel.bind(new InetSocketAddress(port));        //創(chuàng)建selector 選擇器        Selector selector = Selector.open();        //注冊(cè)通道        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);        //輪播查詢        System.out.println("智能水表服務(wù)端(端口:"+port+")已經(jīng)啟動(dòng)");//        如果有就緒狀態(tài)的通道 則select方法返回1        while(true){            while (selector.select()>0){//            因?yàn)橛卸鄠€(gè)通道 ,所以采用集合 獲取所有就緒的通道                //        得到所有就緒狀態(tài)的通道集合到key中                Set<SelectionKey> selectionKeys = selector.selectedKeys(); //selectedKeys所有已經(jīng)就緒的key集合//        轉(zhuǎn)成集合迭代器                Iterator<SelectionKey> iterator = selectionKeys.iterator();                while(iterator.hasNext()){                    SelectionKey selectionKey = iterator.next();                    //有人來連                    if(selectionKey.isAcceptable()){                        acceptOperator(serverSocketChannel,selector);                    }                    //發(fā)過來了已經(jīng)                    else if(selectionKey.isReadable()){                        readOperator(selector,selectionKey);                    }                    //返回水表數(shù)據(jù)                    else if(selectionKey.isWritable()){                        writeOperator(selector,selectionKey);                    }                    iterator.remove();                }            }        }    }    //處理服務(wù)器寫事件    private void writeOperator(Selector selector,SelectionKey selectionKey) {        try {            //有channel可寫,取出可寫的channel            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();            //                    設(shè)計(jì)非阻塞            socketChannel.configureBlocking(false);            socketChannel.write(Charset.forName("UTF-8").encode("數(shù)據(jù)庫存入成功!" ));            //重新將channel注冊(cè)到選擇器上,設(shè)計(jì)為監(jiān)聽            socketChannel.register(selector,SelectionKey.OP_READ);        }catch (IOException e){            e.printStackTrace();        }    }    //    處理讀事件    private void readOperator(Selector selector, SelectionKey selectionKey) throws IOException {        try {            //                    獲取就緒通道            SocketChannel socketChannel = (SocketChannel)selectionKey.channel();//                    設(shè)計(jì)buffer            ByteBuffer buffer = ByteBuffer.allocate(1024);//                    循環(huán)讀客戶端數(shù)據(jù)            int length=0;            String msg="";            if((length=socketChannel.read(buffer))>0){  //讀到buffer里面//                        切換模式                buffer.flip();                msg+=Charset.forName("UTF-8").decode(buffer);  //從buffer里面取數(shù)據(jù) 解碼            }            System.out.println(msg);            String str[]=msg.split(":");            String temp=str[1];            String str2[]=temp.split("、");            SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");            String datetime = tempDate.format(new java.util.Date());            JdbcUtil.find(new User(str2[0],str2[1],str2[2],datetime));            //重新將channel注冊(cè)到選擇器上,設(shè)計(jì)為監(jiān)聽            socketChannel.register(selector,SelectionKey.OP_WRITE);        }catch (IOException e){            selectionKey.cancel();            selectionKey.channel().close();            System.out.println("有客戶端斷連,我已主動(dòng)關(guān)閉");        }                        //光廣播到其他用戶上去//                        if(msg.length()>0){//                            System.out.println(msg);//                            castOtherClient(msg,selector,socketChannel);//                        }    }        //廣播到其他客戶端//    private void castOtherClient(String msg, Selector selector, SocketChannel socketChannel) throws IOException {////        //獲取所有就緒的channel//        Set selectionKeySet = selector.keys();//        循環(huán)處理搜索就緒的channel//        for (SelectionKey selectionKey : selectionKeySet){            獲取每一個(gè)channel//            Channel tarChannel = selectionKey.channel();//            不給自己發(fā)信息//            if(tarChannel instanceof SocketChannel && tarChannel!=socketChannel){//                ((SocketChannel)tarChannel).write(Charset.forName("UTF-8").encode(msg)); //傳輸數(shù)據(jù)是編碼,發(fā)送數(shù)據(jù)是解碼//            }//        }//    }    //處理接收狀態(tài)的通道    private void acceptOperator(ServerSocketChannel serverSocketChannel, Selector selector)  {        try {            //                    獲取連接            SocketChannel socketChannel = serverSocketChannel.accept();//                    設(shè)計(jì)非阻塞            socketChannel.configureBlocking(false);//                     注冊(cè)通道            socketChannel.register(selector,SelectionKey.OP_READ);            //回復(fù)客戶端消息            socketChannel.write(Charset.forName("UTF-8").encode("您已成功連接到服務(wù)器!"));        }catch (IOException e){            e.printStackTrace();        }    }    public static void main(String[] args) throws IOException {        new ChatServer().StratServer(7890);    }}

解釋:
其中我的readOperator函數(shù)是負(fù)責(zé)讀取客戶端傳來的信息。Nio編程核心是通道和選擇器,選擇器通過不斷輪詢,執(zhí)行對(duì)應(yīng)的函數(shù)。
此項(xiàng)目我加入了數(shù)據(jù)庫,如果收到客戶端信息,存入數(shù)據(jù)庫。

2、客戶端代碼

2.1、負(fù)責(zé)發(fā)送的主客戶端

package Client;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Scanner;public class ChatClient {    public void startClient(String name ) throws IOException, InterruptedException {        //        創(chuàng)建通道 綁定主機(jī)和端口        SocketChannel socketChannel = null;            socketChannel = SocketChannel.open(new InetSocketAddress(                    "127.0.0.1", 7890));        //接受服務(wù)端響應(yīng)的數(shù)據(jù)        Selector selector = Selector.open();        socketChannel.configureBlocking(false);        socketChannel.register(selector, SelectionKey.OP_READ);        //創(chuàng)建線程        new Thread(new ClientThread(selector)).start();//負(fù)責(zé)拿到服務(wù)器端數(shù)據(jù)        //向服務(wù)端發(fā)送數(shù)據(jù)        System.out.println("請(qǐng)輸入抄水表編號(hào)、抄水量、抄表員(抄水時(shí)間自動(dòng)生成)(請(qǐng)?jiān)?min中內(nèi)完成)");        Scanner scanner = new Scanner(System.in);        while (scanner.hasNextLine()){            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);            String str = scanner.nextLine(); //鍵盤獲取輸入的內(nèi)容            if(str.length()>0){               socketChannel.write(Charset.forName("UTF-8").encode("客戶端:"+name+":"+str+"(已加載數(shù)據(jù)庫)"));                //System.out.println(Charset.forName("UTF-8").encode(name+":"+str));            }        //設(shè)計(jì)非堵塞模式        socketChannel.configureBlocking(false);        //設(shè)計(jì)buffer    }    }    public static void main(String[] args) throws IOException, InterruptedException {        new ChatClient().startClient("gx");    }}

2.2、負(fù)責(zé)接收服務(wù)器信息的客戶端線程

package Client;import java.io.IOException;import java.net.ConnectException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Iterator;import java.util.Set;public class ClientThread implements Runnable{    private Selector selector;    ClientThread(Selector selector){        this.selector=selector;    }    @Override    public void run() {//        while(true){            for(;;){                try {                    int length=selector.select();                    if(length ==0){                        continue;                    }                    //        得到所有就緒狀態(tài)的通道集合到key中                    Set<SelectionKey> selectionKeys = selector.selectedKeys(); //selectedKeys所有已經(jīng)就緒的key集合                    //        轉(zhuǎn)成集合迭代器                    Iterator<SelectionKey> iterator = selectionKeys.iterator();                    while(iterator.hasNext()){                        SelectionKey selectionKey = iterator.next();                        if(selectionKey.isReadable()){                            readOperator(selector,selectionKey);                        }                        iterator.remove();                    }                } catch (IOException | InterruptedException e) {                    e.printStackTrace();                }            }        }    //    處理接收服務(wù)器信息事件    private void readOperator(Selector selector, SelectionKey selectionKey) throws InterruptedException {        try {            //                    獲取就緒通道            SocketChannel socketChannel = (SocketChannel)selectionKey.channel();//                    設(shè)計(jì)buffer            ByteBuffer buffer = ByteBuffer.allocate(1024);//                    循環(huán)讀客戶端數(shù)據(jù)            int length=0;            String msg="";            if((length=socketChannel.read(buffer))>0){  //讀到buffer里面//                        切換模式                buffer.flip();                msg+= Charset.forName("UTF-8").decode(buffer);  //從buffer里面取數(shù)據(jù) 解碼            }            System.out.println(msg);            //重新將channel注冊(cè)到選擇器上,設(shè)計(jì)為監(jiān)聽            socketChannel.register(selector,SelectionKey.OP_READ);        }catch (IOException e){            selectionKey.cancel();            System.out.println("服務(wù)器中斷 開始準(zhǔn)備重連");            while (true){                try {                    new ChatClient().startClient("gx");                } catch (IOException ioException) {                    System.out.println("正在重連(5s) ");                    //ioException.printStackTrace();                    Thread.sleep(5000);                    continue;                }            }        }    }}

3、關(guān)鍵重連代碼解釋

1 重連代碼解釋

如果服務(wù)器突然關(guān)閉,如果在這里不try catch異常,而是向上拋出的話,隨著服務(wù)器異常關(guān)閉,客戶端也掛了,而且不會(huì)重連。
所以我們需要捕獲這個(gè)異常,并且開始不斷重連。
我寫了一個(gè)死循環(huán),不斷連接,如果連不上他還是會(huì)報(bào)錯(cuò),所以連不上的錯(cuò)也要捕獲異常,不然程序就報(bào)錯(cuò)結(jié)束了,所以捕獲連接沒上的話,continue重新執(zhí)行while循環(huán),直到連接上服務(wù)器。

2 如果客戶端關(guān)閉 那么服務(wù)器也要主動(dòng)關(guān)閉他

4 數(shù)據(jù)庫代碼及實(shí)體類:

如果還想實(shí)現(xiàn)數(shù)據(jù)庫方面代碼,私我

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/125587.html

相關(guān)文章

  • 一篇文章帶你徹底搞懂NIO

    摘要:阻塞當(dāng)進(jìn)行讀寫時(shí),線程是阻塞的狀態(tài)。當(dāng)任何一個(gè)收到數(shù)據(jù)后,中斷程序?qū)酒疬M(jìn)程。接收數(shù)據(jù)當(dāng)收到數(shù)據(jù)后,中斷程序會(huì)給的就緒列表添加引用。當(dāng)接收到數(shù)據(jù),中斷程序一方面修改,另一方面喚醒等待隊(duì)列中的進(jìn)程,進(jìn)程再次進(jìn)入運(yùn)行狀態(tài)如下圖。 本篇文章目的在于基本概念和原理的解釋,不會(huì)貼過多的使用代碼。 什么是NIO Java NIO (New IO)是 Java 的另一個(gè) IO API (來自 jav...

    ziwenxie 評(píng)論0 收藏0
  • Java NIO淺析

    摘要:阻塞請(qǐng)求結(jié)果返回之前,當(dāng)前線程被掛起。也就是說在異步中,不會(huì)對(duì)用戶線程產(chǎn)生任何阻塞。當(dāng)前線程在拿到此次請(qǐng)求結(jié)果的過程中,可以做其它事情。事實(shí)上,可以只用一個(gè)線程處理所有的通道。 準(zhǔn)備知識(shí) 同步、異步、阻塞、非阻塞 同步和異步說的是服務(wù)端消息的通知機(jī)制,阻塞和非阻塞說的是客戶端線程的狀態(tài)。已客戶端一次網(wǎng)絡(luò)請(qǐng)求為例做簡(jiǎn)單說明: 同步同步是指一次請(qǐng)求沒有得到結(jié)果之前就不返回。 異步請(qǐng)求不會(huì)...

    yeooo 評(píng)論0 收藏0
  • 初探Java Socket

    摘要:綁定完成后允許套接字進(jìn)行連接并等待連接。服務(wù)端根據(jù)報(bào)文返回響應(yīng),并關(guān)閉連接。單線程服務(wù)器多進(jìn)程及多線程服務(wù)器復(fù)用服務(wù)器復(fù)用的多線程服務(wù)器單線程服務(wù)器一次只處理一個(gè)請(qǐng)求,直到其完成為止。 前言 本篇文章將涉及以下內(nèi)容: IO實(shí)現(xiàn)Java Socket通信 NIO實(shí)現(xiàn)Java Socket通信 閱讀本文之前最好了解過: Java IO Java NIO Java Concurrenc...

    張漢慶 評(píng)論0 收藏0
  • java同步非阻塞IO

    摘要:的異步即是異步的,也是非阻塞的。但是,也可以進(jìn)行一層稍微薄點(diǎn)的封裝,保留這種多路復(fù)用的模型,比如的,是一種同步非阻塞的模型。系統(tǒng)調(diào)用操作系統(tǒng)的系統(tǒng)調(diào)用提供了多路復(fù)用的非阻塞的系統(tǒng)調(diào)用,這也是機(jī)制實(shí)現(xiàn)需要用到的。 異步IO編程在javascript中得到了廣泛的應(yīng)用,之前也寫過一篇博文進(jìn)行梳理。js的異步IO即是異步的,也是非阻塞的。非阻塞的IO需要底層操作系統(tǒng)的支持,比如在linux上...

    caoym 評(píng)論0 收藏0
  • 少啰嗦!一分鐘帶你讀懂JavaNIO和經(jīng)典IO的區(qū)別

    摘要:的選擇器允許單個(gè)線程監(jiān)視多個(gè)輸入通道。一旦執(zhí)行的線程已經(jīng)超過讀取代碼中的某個(gè)數(shù)據(jù)片段,該線程就不會(huì)在數(shù)據(jù)中向后移動(dòng)通常不會(huì)。 1、引言 很多初涉網(wǎng)絡(luò)編程的程序員,在研究Java NIO(即異步IO)和經(jīng)典IO(也就是常說的阻塞式IO)的API時(shí),很快就會(huì)發(fā)現(xiàn)一個(gè)問題:我什么時(shí)候應(yīng)該使用經(jīng)典IO,什么時(shí)候應(yīng)該使用NIO? 在本文中,將嘗試用簡(jiǎn)明扼要的文字,闡明Java NIO和經(jīng)典IO之...

    Meils 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<