利用Socket实现一个简单的群聊系统

系统需求

1.实现多个用户即时通信的群聊功能

实现分析

1.当服务端接入一个客户端时,为避免阻塞,并接受其他客户端的接入,为该socket开一个线程管理它。

2.当所接入的客户端中,有客户端发送信息时,服务端接收消息,并将此消息发向其他客户端,从而实现简单的群聊功能。

二、使用步骤

1.服务端

利用循环和accept()的阻塞性,在为每一个客户端开一个线程来实现同时接入多个客户端

要注意,每当接收到一个新的客户端,需要将socket存入一个全局的列表,方便服务端对客户端统一管理。

public class Server5 {
    //定义一个全局的列表管理socket
    public static ArrayList<Socket> sockets = new ArrayList<>();

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

        ServerSocket serverSocket = new ServerSocket(8888);

        while(true){
            //等待客户端连接,没有连接时则阻塞
            Socket socket = serverSocket.accept();

            sockets.add(socket);

            //给该socket开一个线程
            new Thread(new ServerThread(socket)).start();
        }
    }
}

     线程所需要实现的功能有接收所对应客户端的消息,并将此消息发送给其他客户端,这里要用到之前的全局列表;还要监测客户端的状态,当socket的连接出现异常时,说明客户端断开了连接,此时需要将socket从全局列表中删除,并将此socket关闭。

public class ServerThread implements Runnable{

    private Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            //向其他客户端发送自己进入了聊天室
            send(socket.getRemoteSocketAddress()+" Enter the room");
            System.out.println(socket.getRemoteSocketAddress()+" Enter the room");
        } catch (IOException e) {
            e.printStackTrace();
        }
        while(true){

            try {
                //调用接受消息的函数
                String s = recive();
                System.out.println(socket.getRemoteSocketAddress()+": "+s);

                //向其他客户端发送接收到的消息
                send(socket.getRemoteSocketAddress()+": "+s);

            } catch (IOException e) {
                try {
                    //出现异常,说明socket断开,客户端断开连接
                    send(socket.getRemoteSocketAddress()+" 滚出了房间!");
                    System.out.println(socket.getRemoteSocketAddress()+"滚出了房间!");

                    //在列表中移除该socket
                    Server5.sockets.remove(socket);
                    socket.close();//关闭socket
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                break;
            }

        }
    }

    //接受客户端的消息
    public String recive() throws IOException {
        BufferedReader serverRecive =
                new BufferedReader(new InputStreamReader(socket.getInputStream()));
        return serverRecive.readLine();
    }


    //向其他客户端发送消息
    public void send(String s) throws IOException {
        ArrayList<Socket> list = Server5.sockets;
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i)!=socket){
                BufferedWriter serverSend =
                        new BufferedWriter(new OutputStreamWriter(list.get(i).getOutputStream()));
                serverSend.write(s);
                serverSend.newLine();
                serverSend.flush();
            }
        }
    }

}

2.客户端

        客户端需要实现,向服务端发送消息,和接收来自服务端的消息;检测服务端的状态;

public class client5 {

    public static void main(String[] args) throws IOException {
        //连接服务器
        Socket socket = new Socket("192.168.29.170", 8888);

        //启动接受消息和发送消息的线程
        new Thread(new Send(socket)).start();
        new Thread(new Reciver(socket)).start();

    }
}

//发送消息
class Send implements Runnable {

    private Socket socket = null;

    public Send(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true) {
            Scanner sc = new Scanner(System.in);
            String s = sc.next();
            try {
                BufferedWriter clientSend =
                        new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                clientSend.write(s);
                clientSend.newLine();
                clientSend.flush();
            } catch (IOException e) {
                System.out.println("服务器关闭!");
                break;
            }
        }
    }
}

//接受消息
class Reciver implements Runnable {

    private Socket socket = null;

    public Reciver(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true) {
            try {
                BufferedReader clientReciver =
                        new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String s = clientReciver.readLine();
                System.out.println(s);
            } catch (IOException e) {
                System.out.println("服务器关闭!");
                break;
            }
        }
    }
}

代码测试

注意看每个端口是不同的,相当于多个客户端

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值