JavaTCP实现多人聊天(修改版)

 服务端

package com.xsh.internet.socket.chat;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ChatServer {
    public static void main(String[] args){
        ServerSocket listen = null;
        Socket socket = null;
        try {
            //创建服务器,设置端口号为9999
            listen = new ServerSocket(9999);
            System.out.println("服务器已启动");
            //创建线程安全的列表,用来存放客户端
            List<Socket> list = Collections.synchronizedList(new ArrayList<>());
            while(true){
                //监听客户
                socket = listen.accept();
                System.out.println(socket.getInetAddress().getHostAddress() + "加入服务器");        
                list.add(socket);
                //创建线程
                new ChatThread(socket, list).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
                listen.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

聊天线程

package com.xsh.internet.socket.chat;

import java.io.*;
import java.net.Socket;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChatThread extends Thread {
    private Socket socket;
    private List<Socket> list;
    public ChatThread(Socket socket, List<Socket> list){
        this.socket = socket;
        this.list = list;
    }
    public void run(){
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while(true) {
                String data = br.readLine();
//退出线程条件                if(data.equals("886")||data.equals("88")||data.equals("byebye")||data.equals("拜拜")||data.equals("再见")){
                    //列表中也要删除该线程
                    list.remove(socket);
                    System.out.println(socket.getInetAddress().getHostAddress() + "退出服务器");
                    break;
                }
                //将你要发送消息的ip地址拿出来
                String regex = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";
                Pattern pattern = Pattern.compile(regex);
                Matcher matcher = pattern.matcher(data);
                String ip = null;
                while (matcher.find()) {
                    ip = matcher.group();
                }
                String[] str = data.split("\\]|:|:");
                data = str[1];
                //获取你要发送的ip地址的Socket,并将消息发送出去
                for (int i = 0; i < list.size(); i++) {
                    if (ip.equals(list.get(i).getInetAddress().getHostAddress())) {
                        Socket socket = list.get(i);
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        bw.write(this.socket.getInetAddress().getHostAddress() + "向您发送:" + data);
                        bw.newLine();
                        bw.flush();
                        break;
                    }
                }
            }
        } catch (IOException e) {
            System.out.println(socket.getInetAddress().getHostAddress() + "异常退出");
            list.remove(socket);
            try {
                socket.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                br.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

package com.xsh.internet.socket.chat;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class ChatClient {
    public static void main(String[] args){
        //读和写两个线程同时运行,可以实现边读边写
        try {
            Socket socket = new Socket("10.9.21.235", 9999);
            System.out.println("成功加入服务器");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        while(true) {
                            System.out.println(br.readLine());
                        }
                    } catch (IOException e) {
                        System.out.println("退出服务器");
                    }
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                        Scanner input = new Scanner(System.in);
                        while(true) {
                            String data = input.next();
                            bw.write(data);
                            bw.newLine();
                            bw.flush();
                            if(data.equals("886")||data.equals("88")||data.equals("byebye")||data.equals("拜拜")||data.equals("再见")){
                                break;
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值