用Socket 写多人聊天室

以下是客户端代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    Socket client;

    // 定义Client的构造器 来请求连接服务器
    public Client() {
        try {
            System.out.println("正在连接...");
            client = new Socket("localhost", 9876);
            System.out.println("连接成功!");
        } catch (IOException e) {
            System.out.println("客户端请求连接失败!");
            e.printStackTrace();
        }
    }

    // 内部类创建线程
    class ClientThread implements Runnable {
        @Override
        public void run() {
            // 接收从服务器发送过来的数据并打印到控制台
            try {
                // 通过getInputStream 读取服务器发过来的字节流,通过转换器转成字符流
                BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String line = null;
                // 按行读取字符流
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                System.out.println("接收服务器数据失败!!");
                e.printStackTrace();
            }
        }
    }

    public void begin() {
        new Thread(new ClientThread()).start();
        PrintWriter pw = null;
        try {
            // 通过getOutputStream 创建一个打印字节流,并转换为打印字符流
            pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
            Scanner sc = new Scanner(System.in);
            //接收控制台输入的字符串并输出
            while (true) {
                pw.write(sc.next());
                pw.flush();
            }
        } catch (Exception e) {
            System.out.println("向控制台发送信息失败");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Client().begin();
    }
}

以下是服务器代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    ServerSocket server;
    List<PrintWriter> allOut;

    // 创建服务器的构造器,并初始化服务器和打印流集合
    Server() throws IOException {
        // 创建服务器
        server = new ServerSocket(9876);
        // 创建打印流集合,统一管理打印流
        allOut = new ArrayList<PrintWriter>();
    }

    // 添加打印流
    public synchronized void add(PrintWriter pw) {
        allOut.add(pw);
    }

    // 移除打印流
    public synchronized void delete(PrintWriter pw) {
        allOut.remove(pw);
    }

    // 打印流输出信息
    public synchronized void sendMessage(String message) {
        for (PrintWriter out : allOut) {
            out.println(message);
            out.flush();
        }
    }

    class ServerThread implements Runnable {
        Socket socket;
        String host;

        // 创建ServerThread的构造器,创建一个socket 并获得他的IP地址
        ServerThread(Socket socket) {
            this.socket = socket;
            host = socket.getInetAddress().getHostAddress();
        }

        @Override
        public void run() {
            PrintWriter pw = null;
            BufferedReader br = null;
            try {
                // 创建socket的输出流
                pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                // 将输出流加到List中
                add(pw);
                sendMessage(host + "上线了,当前人数为: " + allOut.size());

                // 创建socket的输入流
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String line;
                while ((line = br.readLine()) != null) {
                    sendMessage(host + " : " + line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                delete(pw);
                sendMessage(host + "下线了,当前人数为: " + allOut.size());
            }
        }
    }

    public void begin() {
        try {
            while (true) {
                System.out.println("等待客户端连接...");
                Socket socket = server.accept();
                System.out.println("连接成功!");
                // 得到一个实例就新建一个socket的线程
                new Thread(new ServerThread(socket)).start();
            }
        } catch (Exception e) {
            System.out.println("连接客户端失败");
        }
    }

    public static void main(String[] args) {
        try {
            new Server().begin();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值