java中一个服务端对客户端的带界面的聊天室

来源:互联网 发布:蜗牛睡眠知乎 编辑:程序博客网 时间:2024/06/07 01:59

思路:用Swing包创建一个简单的聊天的面板,实现与服务端的通信,关键是将聊天面板发送的Msg传到服务端的Recieve线程中,将服务端Send线程中的Msg发送到聊天面板中显示,因此我选择了用构造方法传参的形式(其实也可以使用static方式)在线程中传入Msg
这段代码只能实现一个服务端同一时间跟多个客户端中的一个聊天,不能实现一个服务端同时跟多个客户端进行群聊

服务端代码:

/** * 实现多个客户端对应一个服务端进行通信 *  * @author wangjue * */public class MyServer {    public static void main(String[] args) {        MyServer ms = new MyServer();        ms.initServer(10010);    }    public void initServer(int port) {        try {            ServerSocket server = new ServerSocket(port);            System.out.println("服务端正等待客户端连接...");            // 表示可以连接多个客户端            while (true) {                Socket socket = server.accept();                System.out.println("已经有一个客户端连接上来了...");                // 启动发消息的线程                new Thread(new SendThread(socket)).start();                //启动收消息的线程                new Thread(new RecieveThread(socket)).start();            }        } catch (IOException e) {            e.printStackTrace();        }    }}
/** * 接收客户端不断传来消息的线程 *  * @author wangjue * */public class RecieveThread implements Runnable {    private Socket socket;    public RecieveThread(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        try {            InputStream ips = socket.getInputStream();            ByteArrayOutputStream bos = new ByteArrayOutputStream();            while (true) {                int t = ips.read();                // 收到换行符为止                while (t != '\n') {                    bos.write(t);                    t = ips.read();                }                byte[] b = bos.toByteArray();                String recieveMsg = new String(b);                System.out.println(recieveMsg);                bos.reset();            }        } catch (IOException e) {            e.printStackTrace();        }    }}
/** * 发送给客户端的线程 */import java.io.OutputStream;import java.net.Socket;import java.util.Date;import java.util.Scanner;public class SendThread implements Runnable{    private Socket socket;    public SendThread(Socket socket){        this.socket = socket;    }    @Override    public void run() {        try {            OutputStream ops = socket.getOutputStream();            while(true) {                Scanner sc = new Scanner(System.in);                String msg = "服务端说:"+sc.nextLine()+"----"+new Date(System.currentTimeMillis())+"\n";                ops.write(msg.getBytes());                ops.flush();                            }                   } catch (IOException e) {            e.printStackTrace();        }    }}

客户端

public class MyClient {    public static void main(String[] args) {        MyClient mc = new MyClient();        mc.initClient("127.0.0.1", 10010);    }    public void initClient(String host, int port) {        try {            Socket socket = new Socket(host, port);            talkUI ui = new talkUI();            ui.initUI();                        // 启动收消息的线程            RecieveThread rt = new RecieveThread(socket, ui);            new Thread(rt).start();            // 启动发消息的线程            SendThread st = new SendThread(socket, ui);            new Thread(st).start();        } catch (Exception e) {            e.printStackTrace();        }    }}
/** * 聊天面板 * @author wangjue * */public class talkUI implements ActionListener{    private JTextArea area1 = new JTextArea(15,30);    private JTextArea area2 = new JTextArea(10,30);    public OutputStream ops;    //在对话框输入的内容    private String sendMsg;    //传给服务端的内容    public String sendMsg2;    public JTextArea getArea1() {        return area1;    }    public void initUI() {         JFrame jf = new JFrame();         jf.setTitle("私人聊天室");         jf.setSize(400,600);         FlowLayout layout = new FlowLayout();         jf.setLayout(layout);         //显示面板         area1.setEditable(false);         jf.add(area1);         //输入面板         jf.add(area2);         //发送按钮         JButton btn = new JButton("发送");         jf.add(btn);         jf.setDefaultCloseOperation(3);         jf.setVisible(true);         btn.addActionListener(this);     }    @Override    public void actionPerformed(ActionEvent e) {        sendMsg  = area2.getText();        sendMsg2 = sendMsg+"\n"; //传给服务端的消息要加入换行符,服务端才能知道什么时候结束接收        //输入的内容要显示在面板上        area1.append("自己说:"+sendMsg+"----"+new Date(System.currentTimeMillis())+"\n");        //点击发送后,输入面板要清空        area2.setText("");        //要每点击一次发送就要将内容写入输出流中        try {            ops.write(sendMsg2.getBytes());                 } catch (IOException e1) {            e1.printStackTrace();        }           }}
/** * 接收服务端传来的消息并显示在面板上 * @author wangjue * */public class RecieveThread implements Runnable {    private Socket socket;    private talkUI ui;//传入面板对象,调用getArea1方法获取area1对象    public RecieveThread(Socket socket,talkUI ui) {        this.socket = socket;        this.ui = ui;    }    @Override    public void run() {        try {            InputStream ips = socket.getInputStream();            ByteArrayOutputStream bos = new ByteArrayOutputStream();            while (true) {                int t = ips.read();                while (t != '\n') {                    bos.write(t);                    t = ips.read();                }                byte[] b = bos.toByteArray();                //收到服务端传来的消息                String msg = new String(b);                //将消息显示在消息面板上                ui.getArea1().append(msg+"\n");                 //将服务端的消息接收到并显示在面板后,清空输入流,下次收到消息后就不会显示上次已经收到的消息                bos.reset();            }        } catch (IOException e) {            e.printStackTrace();        }    }}
/** * 向服务端发送消息 * @author wangjue * */public class SendThread implements Runnable {    private Socket socket;    private talkUI ui; //传入ui对象,调用传给服务端的消息    public SendThread(Socket socket, talkUI ui) {        this.socket = socket;        this.ui = ui;    }    @Override    public void run() {        try {            ui.ops = socket.getOutputStream();                      while (true) {                if(ui.sendMsg2!=null){                    byte[] b = ui.sendMsg2.getBytes();                    ui.ops.write(b);                    ui.ops.flush();                             }            }        } catch (Exception e) {            e.printStackTrace();        }    }}

结果显示:
简单的实现了多个客户端和一个服务端的有界面的通信

0 0
原创粉丝点击