1. 程式人生 > >java 服務端,實現服務端與客戶端之間的通訊以及客戶端之間的通訊

java 服務端,實現服務端與客戶端之間的通訊以及客戶端之間的通訊

此服務端是利用socket進行通訊

ServerSocket serversocket = new ServerSocket(12333);
使用本機的12333埠進行通訊,可以自己選擇
一般選擇10000以後的埠不會與其他服務衝突

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

public class ServerListener extends Thread {

    public void run
() { try { ServerSocket serversocket = new ServerSocket(12333); while (true) { // 多個客戶端連線用while迴圈 Socket socket = serversocket.accept(); // 建立連線 System.out.println("連線成功"); // 將socket傳遞給新的執行緒 ChatSocket cs = new
ChatSocket(socket); cs.start(); ChatManager.getChatManager().add(cs); } } catch (IOException e) { e.printStackTrace(); } } } ``其中的System.out.println("連線成功");這條語句是為了能在控制檯看到是否已經連線成功 在定義一個新的類繼承Thread,用來接收訊息,
import java.io.BufferedReader;
import
java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import mysqlserver.SqlHelper; public class ChatSocket extends Thread { Socket socket; public ChatSocket(Socket s) { this.socket = s; } public void out(String out) { try { socket.getOutputStream().write(out.getBytes("utf-8")); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { BufferedReader read = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8")); String line = null; while ((line = read.readLine()) != null) { System.out.println(line); } read.close(); } catch (IOException e) { e.printStackTrace(); } }
System.out.println(line);

這句程式碼是為了能夠在服務端看到客戶端傳來的訊息
會將所有客戶端發來的訊息都顯示到控制檯上
其中line就是一個客戶端單次傳送過來的訊息,只需要對其進行判斷就能對對客戶端進行操作

服務端只可以有一個所以需要對其進行單例化,定義一個ChatManager類將其getChatManager函式的返回值設為ChatManager,使其能通過此方法獲得ChatManager的物件

import java.util.Vector;

public class ChatManager {
    // 實現單例化
    private ChatManager() {
    };

    private static final ChatManager cm = new ChatManager();

    public static ChatManager getChatManager() {// 返回值為ChatManager
        return cm;
    }

    // 單例化完成
    Vector<ChatSocket> vector = new Vector<ChatSocket>();

    public void add(ChatSocket cs) {// 為當前集合新增chatsocket物件
        vector.add(cs);
    }

    // 某一個執行緒向其他的客戶端傳送資訊
    public void publish(ChatSocket cs, String out) {
        for (int i = 0; i < vector.size(); i++) {// 遍歷所有的執行緒
            ChatSocket csChatSocket = vector.get(i);
            if (csChatSocket != cs)// 判斷不是當前執行緒就傳送此訊息
                csChatSocket.out(out + "\n");
        }
    }

    // 向當前執行緒發信息
    public void publish_present(ChatSocket cs, String out) {
        cs.out(out + "\n");
    }
}

publish函式為想除了當前執行緒之外得到所有客戶端傳送訊息
而publish_present是向當前客戶端傳送訊息(在登入時驗證密碼等多個地方可以用到)

最終只要在主函式中呼叫new ServerListener().start();
就能執行此伺服器

事例:實現客戶端的登入

在類ChatSocket的run方法中

    @Override
    public void run() {
        try {
            BufferedReader read = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
            String line = null;
            while ((line = read.readLine()) != null) {
                System.out.println(line);
                customerlogin(line);
            }
            read.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

定義customerlogin方法

public void customerlogin(String s) {
        String[] a = s.split(" ");
        //將讀取的資料用空格分開,並存在字串陣列中
        //其中頭兩個字串為自己定義的序列
        if (a[0].equals("customer") && a[1].equals("login")) {
            if (SqlHelper.verify_customer(a)) {
//這條if是與資料庫中的資料進行對比,實現登入            
ChatManager.getChatManager().publish_present(this, "customer login true");

            }
        }
    }

客戶端只需要連線服務端的ip和埠就能與服務端進行通訊

附上github地址:點選進入