聊天服务器与多个客户端

时间:2014-07-09 07:42:32

标签: java swing sockets

我是Java编程的初学者。我正在尝试构建一个聊天服务器,其中将有1个服务器和多个客户端(目前只有2个客户端)。

逻辑: 假设有2个客户A和B

当A向B发送消息时,该消息必须首先由服务器处理,然后传递给B,反之亦然。

在窗口中,来自A的消息应显示为(示例)
A:你好 B:你好 A:你好吗?
B:我没事的

问题: 当我首先运行服务器时,它成功运行 但是当我运行客户端时,窗口被卡住了,即它没有响应。

我想知道的是,如何进行上述沟通?什么是有效的代码。

请忽略UI设计。我想解决的只是上面的逻辑

请注意,您可能会发现我的代码效率低下,并且可能还有一些垃圾代码。

班级名称: Server.java

package chatserver;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JFrame;

public class Server {

    Socket soc;

    ServerSocket s = null;

    public Server() throws IOException
    {
        try
        {
            s = new ServerSocket(6633);
            while(true)
            {
                soc =s.accept();
                ServerHandle handle = new ServerHandle(soc);
                Thread t1 = new Thread(handle);
                t1.start();
            }
        }
        catch(Exception e)
        {
            System.out.println(e);
            //should be e.printStackTrace();
        }
        finally
        {
            if(s != null)
            {
                s.close();
            }   
        }
    }

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub

        try {
            new Server();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
    }
}

服务器处理程序类
class Name: ServerHandle.java

package chatserver;

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

public class ServerHandle implements Runnable {

    Socket s1;
    BufferedReader reader;
    PrintWriter write;
    String msg;

    public ServerHandle(Socket s1)
    {
        this.s1 = s1;
    }

    public void run()
    {

        try {
            reader = new BufferedReader(new InputStreamReader(s1.getInputStream()));
            write = new PrintWriter(new OutputStreamWriter(s1.getOutputStream()));

            while((msg = reader.readLine()) != null)
            {
                write.write(msg);   
            }   
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
            try {
                s1.close();
                reader.close();
                write.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

客户类别
班级名称: Client.java

package chatserver;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.net.UnknownHostException;

import javax.swing.*;

public class Client implements ActionListener
{
    JTextArea textArea;
    private JFrame frmChatWindow;
    private JTextArea textArea_1;
    JTextField username;

    JButton submit;
    JFrame j;
    JFrame jf;
    BufferedReader reader;
    PrintWriter write;
    String msg;
    Socket s;

    public Client() throws Exception, IOException
    {
        try
        {
            s = new Socket("localhost", 6633);
            reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            write = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));

            j = new JFrame("PLAIN");
            j.setBounds(500, 150, 300, 400);

            JPanel panel = new JPanel();
            j.add(panel);
            GridBagLayout gb = new GridBagLayout();
            panel.setLayout(gb);

            GridBagConstraints c = new GridBagConstraints();

            JLabel label = new JLabel("User Name");
            c.gridx = 0;
            c.gridy = 0;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.NORTHWEST;
            c.ipadx = 5;
            c.ipady = 5;

            c.insets = new Insets(7, 7, 7, 7);

            panel.add(label, c);

            username = new JTextField(10);

            c.gridx = 1;
            c.gridy = 0;

            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.WEST;
            c.ipadx = 5;
            c.insets = new Insets(7, 7, 7, 7);

            panel.add(username, c);

            JLabel password = new JLabel("Password");
            c.gridx = 0;
            c.gridy = 1;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.WEST;
            c.ipadx = 5;
            c.insets = new Insets(7, 7, 7, 7);

            panel.add(password, c);

            JPasswordField pass = new JPasswordField(10);
            c.gridx = 1;
            c.gridy = 1;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.WEST;
            c.insets = new Insets(7, 7, 7, 7);

            panel.add(pass, c);

            submit = new JButton("Submit");
            c.gridx = 1;
            c.gridy = 6;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.WEST;
            c.insets = new Insets(7, 7, 7, 7);

            panel.add(submit, c);

            submit.addActionListener(this);
            j.setVisible(true);
            j.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

            while ((msg = reader.readLine()) != null)
            {
                display(msg);
            }
        }

        catch (Exception e)
        {
            System.out.println(e);
        }
        finally
        {
            s.close();
            reader.close();
            write.close();
        }
    }

    private void display(String msg2)
    {
        textArea_1.append("Server" + ": " + msg2);
    }

    public void actionPerformed(ActionEvent e)
    {
        // TODO Auto-generated method stub
        j.dispose();
        frmChatWindow = new JFrame();
        frmChatWindow.setResizable(false);
        frmChatWindow.setTitle("Chat Window");
        frmChatWindow.setBounds(100, 100, 316, 300);
        frmChatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        SpringLayout springLayout = new SpringLayout();
        frmChatWindow.getContentPane().setLayout(springLayout);

        textArea = new JTextArea();
        springLayout.putConstraint(SpringLayout.WEST, textArea, 10, SpringLayout.WEST, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.SOUTH, textArea, 31, SpringLayout.SOUTH, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.EAST, textArea, 229, SpringLayout.WEST, frmChatWindow.getContentPane());
        textArea.setLineWrap(true);
        frmChatWindow.getContentPane().add(textArea);

        JButton btnNewButton = new JButton("Send");
        springLayout.putConstraint(SpringLayout.NORTH, textArea, 0, SpringLayout.NORTH, btnNewButton);
        springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton, -58, SpringLayout.SOUTH, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.EAST, btnNewButton, -10, SpringLayout.EAST, frmChatWindow.getContentPane());
        frmChatWindow.getContentPane().add(btnNewButton);

        JButton btnLogout = new JButton("Logout");
        springLayout.putConstraint(SpringLayout.NORTH, btnLogout, 10, SpringLayout.NORTH, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.EAST, btnLogout, -10, SpringLayout.EAST, frmChatWindow.getContentPane());
        frmChatWindow.getContentPane().add(btnLogout);

        textArea_1 = new JTextArea();
        textArea_1.setEditable(false);
        textArea_1.append(null);
        springLayout.putConstraint(SpringLayout.NORTH, textArea_1, 24, SpringLayout.NORTH, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.WEST, textArea_1, 10, SpringLayout.WEST, frmChatWindow.getContentPane());
        springLayout.putConstraint(SpringLayout.SOUTH, textArea_1, -19, SpringLayout.NORTH, textArea);
        springLayout.putConstraint(SpringLayout.EAST, textArea_1, -6, SpringLayout.WEST, btnLogout);
        frmChatWindow.getContentPane().add(textArea_1);

        btnLogout.addActionListener(new Test2());
        btnNewButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent arg0)
            {
                String s = new String();
                s = textArea.getText();
                sendmsg(s);
                getwrite();
            }
        });
        frmChatWindow.setVisible(true);
    }

    private void getwrite()
    {
        write.write(username.getText());
    }

    public void sendmsg(String g)
    {
        textArea_1.append(username.getText() + " " + ": " + g + "\n");
    }

    class Test2 implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            frmChatWindow.dispose();
            j.setVisible(true);
        }
    }

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    new Client();
                }
                catch (IOException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

问题是您正在读取客户端输入和写入客户端输出。基本上你发送任何客户端只发送一个Ping服务器。

<强> ServerHandler.java

    while((msg = reader.readLine()) != null)
    {
        write.write(msg);
    }

这与您在客户端构造函数中初始化Socket相结合会导致UI冻结。

<强> Client.java

    s = new Socket("localhost", 6633);
    reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
    write = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));

就在下面,

    while ((msg = reader.readLine()) != null)
    {
        display(msg);
    }

面向连接的(TCP),多客户端聊天服务器的设计是错误的。您需要坐下来绘制一个关于如何从头开始编写的图表。