日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java私聊_java Socket实现多人群聊与私聊功能

發布時間:2023/12/16 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java私聊_java Socket实现多人群聊与私聊功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文實例為大家分享了java Socket實現多人群聊與私聊的具體代碼,供大家參考,具體內容如下

關于Socket套接字的一些基本知識與認識可以參見上一篇或自行查閱。

ServerSocket和Socket實現群聊與私聊涉及到多線程編程,實現過程的重點是利用Socket通信的原理,即不斷的在服務端和客戶端創建輸入輸出流來相互傳遞、交換數據等以達到通信的目的。具體實現如下:

服務端:

import java.io.*;

import java.net.*;

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ThreadPoolExecutor;

public class TCPServer {

private ServerSocket serverSocket;

/**

* 創建線程池來管理客戶端的連接線程

* 避免系統資源過度浪費

*/

private ExecutorService exec;

// 存放客戶端之間私聊的信息

private Map storeInfo;

public TCPServer() {

try {

serverSocket = new ServerSocket(6789);

storeInfo = new HashMap();

exec = Executors.newCachedThreadPool();

} catch (Exception e) {

e.printStackTrace();

}

}

// 將客戶端的信息以Map形式存入集合中

private void putIn(String key,PrintWriter value) {

synchronized(this) {

storeInfo.put(key, value);

}

}

// 將給定的輸出流從共享集合中刪除

private synchronized void remove(String key) {

storeInfo.remove(key);

System.out.println("當前在線人數為:"+ storeInfo.size());

}

// 將給定的消息轉發給所有客戶端

private synchronized void sendToAll(String message) {

for(PrintWriter out: storeInfo.values()) {

out.println(message);

}

}

// 將給定的消息轉發給私聊的客戶端

private synchronized void sendToSomeone(String name,String message) {

PrintWriter pw = storeInfo.get(name); //將對應客戶端的聊天信息取出作為私聊內容發送出去

if(pw != null) pw.println(message);

}

public void start() {

try {

while(true) {

System.out.println("等待客戶端連接... ... ");

Socket socket = serverSocket.accept();

// 獲取客戶端的ip地址

InetAddress address = socket.getInetAddress();

System.out.println("客戶端:“" + address.getHostAddress() + "”連接成功! ");

/**

* 啟動一個線程,由線程來處理客戶端的請求,這樣可以再次監聽

* 下一個客戶端的連接

*/

exec.execute(new ListenrClient(socket)); //通過線程池來分配線程

}

} catch(Exception e) {

e.printStackTrace();

}

}

/**

* 該線程體用來處理給定的某一個客戶端的消息,循環接收客戶端發送

* 的每一個字符串,并輸出到控制臺

*/

class ListenrClient implements Runnable {

private Socket socket;

private String name;

public ListenrClient(Socket socket) {

this.socket = socket;

}

// 創建內部類來獲取昵稱

private String getName() throws Exception {

try {

//服務端的輸入流讀取客戶端發送來的昵稱輸出流

BufferedReader bReader = new BufferedReader(

new InputStreamReader(socket.getInputStream(), "UTF-8"));

//服務端將昵稱驗證結果通過自身的輸出流發送給客戶端

PrintWriter ipw = new PrintWriter(

new OutputStreamWriter(socket.getOutputStream(), "UTF-8"),true);

//讀取客戶端發來的昵稱

while(true) {

String nameString = bReader.readLine();

if ((nameString.trim().length() == 0) || storeInfo.containsKey(nameString)) {

ipw.println("FAIL");

} else {

ipw.println("OK");

return nameString;

}

}

} catch(Exception e) {

throw e;

}

}

@Override

public void run() {

try {

/*

* 通過客戶端的Socket獲取客戶端的輸出流

* 用來將消息發送給客戶端

*/

PrintWriter pw = new PrintWriter(

new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);

/*

* 將客戶昵稱和其所說的內容存入共享集合HashMap中

*/

name = getName();

putIn(name, pw);

Thread.sleep(100);

// 服務端通知所有客戶端,某用戶上線

sendToAll("[系統通知] “" + name + "”已上線");

/*

* 通過客戶端的Socket獲取輸入流

* 讀取客戶端發送來的信息

*/

BufferedReader bReader = new BufferedReader(

new InputStreamReader(socket.getInputStream(), "UTF-8"));

String msgString = null;

while((msgString = bReader.readLine()) != null) {

// 檢驗是否為私聊(格式:@昵稱:內容)

if(msgString.startsWith("@")) {

int index = msgString.indexOf(":");

if(index >= 0) {

//獲取昵稱

String theName = msgString.substring(1, index);

String info = msgString.substring(index+1, msgString.length());

info = name + ":"+ info;

//將私聊信息發送出去

sendToSomeone(theName, info);

continue;

}

}

// 遍歷所有輸出流,將該客戶端發送的信息轉發給所有客戶端

System.out.println(name+":"+ msgString);

sendToAll(name+":"+ msgString);

}

} catch (Exception e) {

// e.printStackTrace();

} finally {

remove(name);

// 通知所有客戶端,某某客戶已經下線

sendToAll("[系統通知] "+name + "已經下線了。");

if(socket!=null) {

try {

socket.close();

} catch(IOException e) {

e.printStackTrace();

}

}

}

}

}

public static void main(String[] args) {

TCPServer server = new TCPServer();

server.start();

}

}

客戶端:

import java.io.*;

import java.net.*;

import java.util.Scanner;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ThreadPoolExecutor;

public class TCPClient {

static private Socket clientSocket;

public TCPClient() {}

public static void main(String[] args) throws Exception {

Scanner scanner = new Scanner(System.in);

String serverIP;

System.out.println("請設置服務器IP:");

serverIP = scanner.next();

clientSocket = new Socket(serverIP, 6789);

TCPClient client = new TCPClient();

client.start();

}

public void start() {

try {

Scanner scanner = new Scanner(System.in);

setName(scanner);

// 接收服務器端發送過來的信息的線程啟動

ExecutorService exec = Executors.newCachedThreadPool();

exec.execute(new ListenrServser());

// 建立輸出流,給服務端發信息

PrintWriter pw = new PrintWriter(

new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"), true);

while(true) {

pw.println(scanner.nextLine());

}

} catch(Exception e) {

e.printStackTrace();

} finally {

if (clientSocket !=null) {

try {

clientSocket.close();

} catch(IOException e) {

e.printStackTrace();

}

}

}

}

private void setName(Scanner scan) throws Exception {

String name;

//創建輸出流

PrintWriter pw = new PrintWriter(

new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"),true);

//創建輸入流

BufferedReader br = new BufferedReader(

new InputStreamReader(clientSocket.getInputStream(),"UTF-8"));

while(true) {

System.out.println("請創建您的昵稱:");

name = scan.nextLine();

if (name.trim().equals("")) {

System.out.println("昵稱不得為空");

} else {

pw.println(name);

String pass = br.readLine();

if (pass != null && (!pass.equals("OK"))) {

System.out.println("昵稱已經被占用,請重新輸入:");

} else {

System.out.println("昵稱“"+name+"”已設置成功,可以開始聊天了");

break;

}

}

}

}

// 循環讀取服務端發送過來的信息并輸出到客戶端的控制臺

class ListenrServser implements Runnable {

@Override

public void run() {

try {

BufferedReader br = new BufferedReader(

new InputStreamReader(clientSocket.getInputStream(), "UTF-8"));

String msgString;

while((msgString = br.readLine())!= null) {

System.out.println(msgString);

}

} catch(Exception e) {

e.printStackTrace();

}

}

}

}

運行結果:

開始自己的實現也不是很完整,后來也是借鑒別人比較好的思想后完善的,權當分享。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

總結

以上是生活随笔為你收集整理的java私聊_java Socket实现多人群聊与私聊功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。