天天看點

Android聊天室(伺服器)

Android聊天室(伺服器)

作者:黑衣俠客

一.前言:

本篇部落格承接的是上一篇《Android聊天室(用戶端)》

二.準備:

伺服器主要涉及的是:

Java網絡程式設計

三.編譯器:

伺服器的代碼全部寫入idea中,當然寫入eclipse也可以,操作時,先将伺服器打開運作,然後操作用戶端,我操作時,是PC端作為伺服器,手機和虛拟機作為

用戶端,這裡需要注意的是:手機必須和電腦連接配接同一個WiFi,如果用虛拟機的話,則就省去了這些麻煩。(虛拟機和電腦本就是連接配接同一個WiFi)

四.代碼:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
    public static void main(String[] args){
        //startServer=new startServer();
        new startServer().start();//new 一個線程對象開始啟動(由于startServer類繼承了Thread)
    }
    public static ArrayList<UserThread> socketList=new ArrayList<UserThread>();//建立一個泛型是UserThread(UserThread是下面的一個類)的動态數組
    public static startServer startServer;
    static class startServer extends Thread{
        public void run(){
           try{
               ServerSocket serverSocket = new ServerSocket(6666);
               //建立端口值為:6666的ServerSocket對象
               while(true){//死循環
                   Socket socket = serverSocket.accept();//建立socket對象,用于接受用戶端的請求
                   System.out.println(""+socket);//用于顯示用戶端的IP位址,用戶端的端口号,以及電腦的端口号
                   UserThread userThread = new UserThread(socket);//通過下面定義的UserTread的有參構造,建立userThread對象
                   Server.socketList.add(userThread);
                   new Thread(userThread).start();//開啟輸入輸出流線程
               }
           }catch(IOException e){
               e.printStackTrace();
           }
        }
    }
    static class UserThread implements Runnable{
        private Socket skt;
        private DataOutputStream dos;
        private DataInputStream dis;
        public DataOutputStream getDos(){//傳回輸出流
            return dos;
        }
        public void setDos(DataOutputStream dos){//給輸出流傳遞參數
            this.dos=dos;
        }
        public DataInputStream getDis(){//傳回輸入流
            return dis;
        }
        public void setDis(DataInputStream dis){//給輸入流傳遞參數
            this.dis=dis;
        }
        public UserThread(Socket socket){//構造有參構造
            skt=socket;
        }
        @Override
        public void run(){
            try{
                dos= new DataOutputStream(skt.getOutputStream());//擷取輸出流(準備從伺服器給其他的用戶端發消息)
                dis= new DataInputStream(skt.getInputStream());//接收用戶端發過來的消息(輸入流)
                String recMsg ="";
                while(true){//使伺服器無限循環
                    if(!"".equals(recMsg=dis.readUTF())){//讀取輸入流的消息,并把消息傳到recMsg中
                        System.out.println("收到一條消息"+ recMsg);//顯示:收到一條消息+“傳入的消息”
                        for(UserThread s:socketList){//增強for循環
                            if(s.equals(this)){
                                continue;
                            }
                            try{
                                s.getDos().writeUTF(recMsg);//将UTF-8的字元串寫入位元組流
                            }catch(IOException e){
                                socketList.remove(s);//将s從動态數組socketList中删除
                                e.printStackTrace();
                            }
                        }
                        recMsg="";//recMsg内容重新重新整理
                    }
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}
           

總結:

到目前為止,用戶端和伺服器部落格已全部完成,源碼在下一篇部落格,總之,這次Android聊天室寫的十分艱辛,裡面存在許多沒有考慮的漏洞,不過還好,實作了基本的群聊功能,現在Android聊天室告于段落了,可以繼續學習android知識了,另外在伺服器裡有些重要的細節,下面我會提供一些這方面知識的連結:

有關dos.writeUTF的長度問題

Java中的增強for循環

有關readUTF()和writeUTF()知識的講解

ServerSocket詳解