欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)簡(jiǎn)單的聊天室功能

 更新時(shí)間:2022年06月10日 08:48:28   作者:老徐··  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單的聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java實(shí)現(xiàn)簡(jiǎn)單聊天室功能的具體代碼,供大家參考,具體內(nèi)容如下

一、客戶端的創(chuàng)建

1.我們可以用Socket來(lái)創(chuàng)建客戶端

/**
? *@類名 Client
? *@描述 TODO 客戶端 1
? *@版本 1.0
? *@創(chuàng)建人 XuKang
? *@創(chuàng)建時(shí)間 2020/9/24 16:18
? **/
public class Client {
?? ?public static void main(String[] args) throws UnknownHostException, IOException {
?? ??? ?System.out.println("-----Client1-----");
?? ??? ?BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
?? ??? ?System.out.println("請(qǐng)輸入用戶名:");
?? ??? ?String name =br.readLine();
?? ??? ?//1、建立連接: 使用Socket創(chuàng)建客戶端 +服務(wù)的地址和端口
?? ??? ?Socket client =new Socket("localhost",8888);
?? ??? ?//2、客戶端發(fā)送消息
?? ??? ?new Thread(new Send(client,name)).start(); ?
?? ??? ?new Thread(new Receive(client)).start();
?? ?}
}

2.這時(shí)我們需要接受其他客戶端發(fā)送的數(shù)據(jù),我們需要?jiǎng)?chuàng)建一個(gè)客戶端的接收方法和發(fā)送方法,我可以用阻塞式的方式進(jìn)行接收和發(fā)送,考慮到多線程的安全性,可以實(shí)現(xiàn)Runnable

1.Send發(fā)送端:

/**
? *@類名 Send
? *@描述 TODO 使用多線程封裝:發(fā)送端
? *@版本 1.0
? *@創(chuàng)建人 XuKang
? *@創(chuàng)建時(shí)間 2020/9/24 16:23
? **/
public class Send implements Runnable {
?? ?private BufferedReader console ;
?? ?private DataOutputStream dos;
?? ?private Socket client;
?? ?private boolean isRunning;
?? ?private String name;
?? ?public Send(Socket client,String name) {
?? ??? ?this.client =client;
?? ??? ?console =new BufferedReader(new InputStreamReader(System.in));
?? ??? ?this.isRunning = true;
?? ??? ?this.name = name;
?? ??? ?try {
?? ??? ??? ?dos =new DataOutputStream(client.getOutputStream());
?? ??? ??? ?//發(fā)送名稱
?? ??? ??? ?send(name);
?? ??? ?} catch (IOException e) {
?? ??? ??? ?System.out.println("==1==");
?? ??? ??? ?this.release();
?? ??? ?}?? ?
?? ?}
?? ?@Override
?? ?public void run() {
?? ??? ?while(isRunning) {
?? ??? ??? ?String msg = getStrFromConsole();
?? ??? ??? ?if(!msg.equals("")) {
?? ??? ??? ??? ?send(msg);
?? ??? ??? ?}
?? ??? ?}
?? ?}?? ?
?? ?//發(fā)送消息
?? ?private void send(String msg) {
?? ??? ?try {
?? ??? ??? ?dos.writeUTF(msg);
?? ??? ??? ?dos.flush();
?? ??? ?} catch (IOException e) {
?? ??? ??? ?System.out.println(e);
?? ??? ??? ?System.out.println("===3==");
?? ??? ??? ?release();
?? ??? ?}
?? ?}
?? ?/**
?? ? * 從控制臺(tái)獲取消息
?? ? * @return
?? ? */
?? ?private String getStrFromConsole() {
?? ??? ?try {
?? ??? ??? ?return ?console.readLine();
?? ??? ?} catch (IOException e) {
?? ??? ??? ?e.printStackTrace();
?? ??? ?}
?? ??? ?return "";
?? ?}
?? ?//釋放資源
?? ?private void release() {
?? ??? ?this.isRunning = false;
?? ??? ?CloseUtils.close(dos,client);
?? ?}

}

2.接收端

/**
? *@類名 Receive
? *@描述 TODO 使用多線程封裝:接收端
? *@版本 1.0
? *@創(chuàng)建人 XuKang
? *@創(chuàng)建時(shí)間 2020/9/24 16:22
? **/
public class Receive implements Runnable {
?? ?private DataInputStream dis ;
?? ?private Socket client;
?? ?private boolean isRunning;
?? ?public Receive(Socket client) {
?? ??? ?this.client = client;
?? ??? ?this.isRunning = true;
?? ??? ?try {
?? ??? ??? ?dis =new DataInputStream(client.getInputStream());
?? ??? ?} catch (IOException e) {
?? ??? ??? ?System.out.println("====離開(kāi)一位=====");
?? ??? ??? ?release();
?? ??? ?}
?? ?}
?? ?//接收消息
?? ?private String receive() {
?? ??? ?String msg ="";
?? ??? ?try {
?? ??? ??? ?msg =dis.readUTF();
?? ??? ?} catch (IOException e) {
?? ??? ??? ?System.out.println("====接收消息異常====");
?? ??? ??? ?release();
?? ??? ?}
?? ??? ?return msg;
?? ?}
?? ?
?? ?@Override
?? ?public void run() {?? ??? ?
?? ??? ?while(isRunning) {
?? ??? ??? ?String msg =receive();
?? ??? ??? ?if(!msg.equals("")) {
?? ??? ??? ??? ?System.out.println(msg);
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?//釋放資源
?? ?private void release() {
?? ??? ?this.isRunning = false;
?? ??? ?CloseUtils.close(dis,client);
?? ?}

}

3.統(tǒng)一釋放資源的方法可以提出,服務(wù)的也用得上

/**
? *@類名 CloseUtils
? *@描述 TODO 工具類,統(tǒng)一釋放資源
? *@版本 1.0
? *@創(chuàng)建人 XuKang
? *@創(chuàng)建時(shí)間 2020/9/24 16:20
? **/
public class CloseUtils {
?? ?/**
?? ? * 釋放資源
?? ? */
?? ?public static void close(Closeable... targets ) {
?? ??? ?for(Closeable target:targets) {
?? ??? ??? ?try {
?? ??? ??? ??? ?if(null!=target) {
?? ??? ??? ??? ??? ?target.close();
?? ??? ??? ??? ?}
?? ??? ??? ?}catch(Exception e) {

?? ??? ??? ?}
?? ??? ?}
?? ?}
}

二、客戶端的創(chuàng)建

服務(wù)端用ServerSocket創(chuàng)建,如果我們吧服務(wù)的和客戶端看成事一個(gè)通信通道(Channel),那么每個(gè)客戶端的接入都會(huì)創(chuàng)建一個(gè)通信通道,那么通信通道的創(chuàng)建也需要實(shí)現(xiàn)多線程,可以實(shí)現(xiàn)Runnable接口,我們存放通道可以用線程容器CopyOnWriteArrayList來(lái)存放通道。

/**
? *@類名 Chat
? *@描述 TODO Socket服務(wù)端(測(cè)試類)
? *@版本 1.0
? *@創(chuàng)建人 XuKang
? *@創(chuàng)建時(shí)間 2020/9/24 16:17
? **/
public class Chat {

?? ?private static CopyOnWriteArrayList<Channel> all =new CopyOnWriteArrayList<Channel>();

?? ?public static void main(String[] args) throws IOException {
?? ??? ?System.out.println("-----Server-----");
?? ??? ?// 1、指定端口 使用ServerSocket創(chuàng)建服務(wù)器
?? ??? ?ServerSocket server =new ServerSocket(8888);
?? ??? ?// 2、阻塞式等待連接 accept
?? ??? ?while(true) {
?? ??? ??? ??? ?Socket ?client =server.accept();?
?? ??? ??? ??? ?System.out.println("一個(gè)客戶端建立了連接");
?? ??? ??? ??? ?Channel c =new Channel(client);
?? ??? ??? ??? ?all.add(c); //管理所有的成員
?? ??? ??? ??? ?new Thread(c).start();?? ??? ??? ?
?? ??? ??? ?}?? ??? ?
?? ??? ?}
?? ??? ?//一個(gè)客戶代表一個(gè)Channel
?? ??? ?static class Channel implements Runnable{
?? ??? ??? ?private DataInputStream dis;
?? ??? ??? ?private DataOutputStream dos;
?? ??? ??? ?private Socket ?client;?? ??? ??? ?
?? ??? ??? ?private boolean isRunning;
?? ??? ??? ?private String name;
?? ??? ??? ?public Channel(Socket ?client) {
?? ??? ??? ??? ?this.client = client;
?? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ?dis = new DataInputStream(client.getInputStream());
?? ??? ??? ??? ??? ?dos =new DataOutputStream(client.getOutputStream());
?? ??? ??? ??? ??? ?isRunning =true;
?? ??? ??? ??? ??? ?//獲取名稱
?? ??? ??? ??? ??? ?this.name =receive();//退出出聊天室
?? ??? ??? ??? ??? ?//歡迎你的到來(lái)
?? ??? ??? ??? ??? ?this.send("歡迎你的到來(lái)");
?? ??? ??? ??? ??? ?sendOthers(this.name+"來(lái)了徐康聊天室",true);//暫時(shí)固定為私聊
?? ??? ??? ??? ?} catch (IOException e) {
?? ??? ??? ??? ??? ?System.out.println("---1------");
?? ??? ??? ??? ??? ?release();?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?}?? ??? ??? ?
?? ??? ??? ?}
?? ??? ??? ?//接收消息
?? ??? ??? ?private String receive() {
?? ??? ??? ??? ?String msg ="";
?? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ?msg =dis.readUTF();
?? ??? ??? ??? ?} catch (IOException e) {
?? ??? ??? ??? ??? ?System.out.println("---2------");
?? ??? ??? ??? ??? ?release();
?? ??? ??? ??? ?}
?? ??? ??? ??? ?return msg;
?? ??? ??? ?}
?? ??? ??? ?//發(fā)送消息
?? ??? ??? ?private void send(String msg) {
?? ??? ??? ??? ?try {
?? ??? ??? ??? ??? ?dos.writeUTF(msg);
?? ??? ??? ??? ??? ?dos.flush();
?? ??? ??? ??? ?} catch (IOException e) {
?? ??? ??? ??? ??? ?System.out.println("---3------");
?? ??? ??? ??? ??? ?release();
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?/**
?? ??? ??? ? * @方法名 sendOthers
?? ??? ??? ? * @描述 TODO 群聊:獲取自己的消息,發(fā)給其他人,需要設(shè)置isSys為false
?? ??? ??? ? * ?? ??? ? TODO 私聊: 約定數(shù)據(jù)格式: @xxx:msg
?? ??? ??? ? * @參數(shù) msg 發(fā)送內(nèi)容
?? ??? ??? ? * @返回值
?? ??? ??? ? * @創(chuàng)建人 XuKang
?? ??? ??? ? * @創(chuàng)建時(shí)間 2020/9/24 16:28
?? ??? ??? ? */
?? ??? ??? ?private void sendOthers(String msg,boolean isSys) {
?? ??? ??? ??? ?boolean isPrivate = msg.startsWith("@");
?? ??? ??? ??? ?if(isPrivate) { //私聊
?? ??? ??? ??? ??? ?int idx =msg.indexOf(":");
?? ??? ??? ??? ??? ?//獲取目標(biāo)和數(shù)據(jù)
?? ??? ??? ??? ??? ?String targetName = msg.substring(1,idx);
?? ??? ??? ??? ??? ?msg = msg.substring(idx+1);
?? ??? ??? ??? ??? ?for(Channel other: all) {
?? ??? ??? ??? ??? ??? ?if(other.name.equals(targetName)) {//目標(biāo)
?? ??? ??? ??? ??? ??? ??? ?other.send(this.name +"悄悄地對(duì)您說(shuō):"+msg);
?? ??? ??? ??? ??? ??? ??? ?break;
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}else {?? ??? ??? ??? ?
?? ??? ??? ??? ??? ?for(Channel other: all) {
?? ??? ??? ??? ??? ??? ?if(other==this) { //自己
?? ??? ??? ??? ??? ??? ??? ?continue;
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ??? ?if(!isSys) {
?? ??? ??? ??? ??? ??? ??? ?other.send(this.name +"對(duì)所有人說(shuō):"+msg);//群聊消息
?? ??? ??? ??? ??? ??? ?}else {
?? ??? ??? ??? ??? ??? ??? ?other.send(msg); //系統(tǒng)消息
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ??? ?//釋放資源
?? ??? ??? ?private void release() {
?? ??? ??? ??? ?this.isRunning = false;
?? ??? ??? ??? ?CloseUtils.close(dis,dos,client);
?? ??? ??? ??? ?//退出
?? ??? ??? ??? ?all.remove(this);
?? ??? ??? ??? ?sendOthers(this.name+"離開(kāi)大家庭...",true);
?? ??? ??? ?}
?? ??? ??? ?@Override
?? ??? ??? ?public void run() {
?? ??? ??? ??? ?while(isRunning) {
?? ??? ??? ??? ??? ?String msg = receive() ;
?? ??? ??? ??? ??? ?if(!msg.equals("")) {
?? ??? ??? ??? ??? ??? ?//send(msg);
?? ??? ??? ??? ??? ??? ?sendOthers(msg,false);
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
}

三、效果如下

1.啟動(dòng)服務(wù)端

2.啟動(dòng)客戶端

3.發(fā)送消息

總結(jié)

此案例只能用來(lái)打發(fā)時(shí)間,入門網(wǎng)絡(luò)編程可以參考一下,真正的開(kāi)發(fā)不會(huì)這么弄。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論