中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【移動開發】WIFI熱點通信(二)

發布時間:2020-07-18 12:34:06 來源:網絡 閱讀:7060 作者:zhf651555765 欄目:開發技術

      相信大家在上一篇中已經了解了Android中WIFI熱點通信的相關操作知識(http://smallwoniu.blog.51cto.com/3911954/1536126),今天我們將在上一篇代碼基礎之上進行Socket編程,實現一個簡單的多人聊天室功能,以達到熱點網絡上的通信目的。

    首先,我們先來看一張最終效果圖:


【移動開發】WIFI熱點通信(二)<=======>【移動開發】WIFI熱點通信(二)

(說明:由于目前作服務器端的手機,只是實現了數據的接收和轉發,自己發送的數據并未顯示到自己的界面上,還需大家完善。。。)


一.框架搭建

在上一章的代碼基礎上,新增加了四個類:

    GameServer:服務器端實現。

    SocketClient:客戶端實現類。

    ChatAdapter:聊天列表適配器。

    ChatMessage:聊天信息實體。

    GroupChatActivity:聊天室Acitivity。

1.1.相關類圖

在熱點連接成功后,開始聊天通信過程,服務器端與客戶端的類實現如下圖所示:

【移動開發】WIFI熱點通信(二)

1.2.說明:

服務端:套接字GameServer,端口和套接字監聽函數beginListen(),接收數據的函數serverAcceptClientMsg(),發送數據的函數sendMsgToAllCLients,以及網絡通訊流BufferedReader。

客戶端:套接字SocketClient,套接字連接函數startConnServer(),接收數據的函數acceptGameServerMsg(),發送數據的函數sendMsg()。

前面提到過創建熱點成功后,會自動在當前手機后臺創建GameServer,同時開啟線程監聽端口并等待連接,當其余玩家成功連接上熱點后,每個手機客戶端后臺對應會創建一個獨立的Socket,用于發送和接收消息。在客戶端中通過client.getInputStream()接收數數據,ClientMsgListener.handlerHotMsg(getSMsg)將數據反映到UI界面上,最終實現了客戶端接收服務器端數據刷新UI界面的功能。


二.通信模塊


    2.1.服務器端

由于軟件的通信載體是在手機上,所以在創建完成熱點之后,在后臺也同時創建了游戲的服務器,開啟了監聽PORT線程,等待其他客戶端連接。這樣設計的目的是為了在當有其他手機端連接上指定WIFI熱點時就與后臺服務器端進行了連接,即實現了TCP/IP通訊前期準備。主要業務設計如圖所示:

【移動開發】WIFI熱點通信(二)

核心代碼:

  •  beginListenandAcceptMsg()

 /** init server to listen **/
    public void beginListenandAcceptMsg() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try { // init server
                    mServerSocket = new ServerSocket();
                    mServerSocket.setReuseAddress(true);
                    InetSocketAddress address = new InetSocketAddress(mPort);
                    mServerSocket.bind(address);
                    mServerMsgListener.handlerHotMsg(Global.INT_SERVER_SUCCESS);
                    Log.i(TAG, "server  =" + mServerSocket);
                } catch (SocketException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //server accept from socket msg
                if(mServerSocket != null) {
                    while(onGoinglistner) {
                        try {
                            Socket socket = mServerSocket.accept();
                            if(socket != null) {
                                if(!socketQueue.contains(socket)) {
                                    socketQueue.add(socket);
                                    count++; //記錄連接人數
                                }
                                Log.i(TAG, "接收客戶端消息" + socket);
                                serverAcceptClientMsg(socket);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }
  • serverAcceptClientMsg()

 /**
     * accept from socket msg
     * @param socket
     */
    private void serverAcceptClientMsg(final Socket socket) {
        new Thread(new Runnable(){
            @Override
            public void run() {
                while(!socket.isClosed()) {
                    try {
                    //此處可以根據連接的客戶端數量count做一些數據分發等操作。
                        //接收客戶端消息
                    in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                        String str = in.readLine();
                        if(str == null || str.equals("")) {
                            break;
                        }
                        Log.i(TAG, "client" + socket + "str =" + str);
                    mServerMsgListener.handlerHotMsg(str);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
  • sendMsg()

/**send msg to the socket**/
    public void sendMsg(Socket client, String chatMsg) {
        Log.i(TAG, "into sendMsg(final Socket client,final ChatMessage msg) msg = " + chatMsg);
        PrintWriter out = null;
        if (client.isConnected()) {
            if (!client.isOutputShutdown()) {
                try {
                    out = new PrintWriter(client.getOutputStream());
                    out.println(chatMsg);
                    out.flush();
                    Log.i(TAG, "into sendMsg(final Socket client,final ChatMessage msg) msg = " + chatMsg + " success!");
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "into sendMsg(final Socket client,final ChatMessage msg) fail!");
                }
            }
        }
        Log.i(TAG, "out sendMsg(final Socket client,final ChatMessage msg) msg = " + chatMsg);
    }


    2.2.客戶端

        這里的客戶端建立指的是當其他手機在該軟件的WIFI管理界面上,點擊可用WIFI列表中指定的WIFI進行連接操作,連接成功后,會在后臺創建客戶端,與服務器相連。主要業務設計如圖所示:

【移動開發】WIFI熱點通信(二)

核心代碼:

  • connServerandAcceptMsg()

/**after hot pot created and connected successful , start connect GameServer**/
    public void connServerandAcceptMsg() {
        Log.i(TAG, "into connectServer()");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    client = new Socket(site, port);
                    Log.i(TAG, "Client is created! site:" + site + " port:" + port);
                    
                    //callback
                    mClientMsgListener.handlerHotMsg(Global.INT_CLIENT_SUCCESS);
                    
                    //accept msg from GameServer
                    acceptGameServerMsg();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    mClientMsgListener.handlerErorMsg(Global.INT_CLIENT_FAIL);
                } catch (IOException e) {
                    e.printStackTrace();
                    mClientMsgListener.handlerErorMsg(Global.INT_CLIENT_FAIL);
                }
            }
        }).start();
        Log.i(TAG, "out connectServer()");
    }
  • acceptGameServerMsg()

/**accept msg from GameServer**/
    private void acceptGameServerMsg() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(onGoinglistner){
                    if(client != null && client.isConnected()) {
                        if(!client.isInputShutdown()) {
                            try {
                                in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                                String getSMsg = in.readLine();
                                Log.i(TAG, "into acceptMsg()  SMsg =" + getSMsg);
                                if(getSMsg != null || !getSMsg.equals("")) {
                                    //callback
                                mClientMsgListener.handlerHotMsg(getSMsg);
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }).start();
    }
  • sendMsg()

/**send msg to GameServer**/
    public String sendMsg(final String chatMsg) {
        Log.i(TAG, "into sendMsgsendMsg(final ChatMessage msg)  msg =" + chatMsg);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (client != null && client.isConnected()) {
                        if (!client.isOutputShutdown()) {
                            PrintWriter out = new PrintWriter(client.getOutputStream());
                            out.println(chatMsg);
                            // out.println(JsonUtil.obj2Str(msg));
                            Log.i(TAG, "成功發送msg =" + chatMsg);
                            out.flush();
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "client snedMsg error!");
                }
            }
        }).start();
        return "";
    }

以上兩大部分為Socket編程部分,為了能夠將數據反映到UI 前臺,這里我們將每次線程接收到的數據先以接口回調方法( mClientMsgListener.handlerHotMsg(getSMsg);)的形式傳遞,在其對應的方法中再利用Handler消息機制將數據發送到各自對應的Handler中,最后根據邏輯將其反映到UI上,以上就是代碼的大體流程。


2.3.通信過程

下載過完整代碼的朋友就會發現代碼中許多重要的方法中我加入了Log,目的就是為了方便自己能夠更加清晰的了解整個代碼的流程,當然大家也可以在此基礎上進行不斷的修改和完善

  • 點擊創建熱點按鈕:

【移動開發】WIFI熱點通信(二)












  • 點擊搜索熱點按鈕:

【移動開發】WIFI熱點通信(二)













  • 點擊列表“WIFI-TEST”進行連接

【移動開發】WIFI熱點通信(二)


三.總結


1.此案例由于是從本人畢業設計中扒下來的,可能現在有些地方代碼框架設計的不是很合理,如:GroupChatActivity就是為了方便實現聊天功能后添加的,大家在學習完之后可以在Activity跳轉時的基礎上,進一步按照自己的邏輯來實現一些東西。

 

    2.UI如何更新?

     服務器端只是實現數據轉發,未對自己發送數據進行顯示,了解了整個代碼的同學可能已經發現不論是Server還是Client端,在接收到數據之后,我們通過各自的監聽器(mServerMsgListener,mClientMsgListener)來回調對應的方法(handlerHotMsg,handlerErrorMsg),在方法中我們將數據添加msg.obj中,最終以消息傳遞的方式發送到各自對應的handler中(clientHandler,serverHandler),在那里我們就可以根據數據來更新界面。

 

3.題外話:

     要是有人對熱點通信特別感興趣,想在此的基礎之上開發小游戲,前臺游戲繪制界面就不用多說了,我主要想說的是后臺數據部分,最好能給所有操作制定了一系列對應的數據規則,如:出牌操作:在傳輸的數據串前面加上規則字符---->“《#CARD》+數據段”,之后作為整體發送出去,這樣的話,接收方在接收到數據后可以方便的更新UI,實現對應的游戲動畫。(個人經驗,僅供參考)


×××:http://down.51cto.com/data/1856373




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临泉县| 宜州市| 黄山市| 慈溪市| 东海县| 吴桥县| 施秉县| 宁强县| 黑山县| 建始县| 忻城县| 罗定市| 临潭县| 五家渠市| 延吉市| 红安县| 广东省| 东阿县| 随州市| 临猗县| 禄劝| 石楼县| 福鼎市| 六枝特区| 墨江| 青田县| 洞头县| 襄城县| 来凤县| 筠连县| 旬邑县| 海城市| 平定县| 阿拉尔市| 郓城县| 象山县| 巴林右旗| 乌鲁木齐县| 启东市| 呼伦贝尔市| 石河子市|