客户无法相互沟通

时间:2016-12-03 20:07:31

标签: java multithreading sockets server client

我写了一个让多个用户聊天的聊天程序。问题是客户端无法看到其他客户输入的内容。服务器运行良好,它接受多个客户端及其输入。我创建了一个ArrayList来存储我服务器中的客户端列表,以便他们查看其他客户端输入的内容,但它似乎无法正常工作。

这是我的代码

服务器

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
    public class myServerSocket {

        int portNumber = 4434;
        ServerSocket serverSocket = null;
        Socket clientSocket;
        ArrayList<myServerSocketRunnable> clients = new ArrayList<myServerSocketRunnable>();

        public void runServer() {
            try {
                while(true) {
                    serverSocket = new ServerSocket(portNumber);
                }
            } catch(IOException aww) {
                System.out.println(aww.getMessage());
                aww.printStackTrace();
            }

            try {
                while(true) {
                    clientSocket = serverSocket.accept();
                    myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
                    clients.add(client);
                    new Thread(new myServerSocketRunnable(clientSocket)).start();
                }
            } catch(IOException aww) {
                System.out.println(aww.getMessage()+"\n");
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }



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

public class myServerSocketRunnable extends Thread {

    protected Socket clientSocket = null;
    BufferedReader in;
    PrintWriter out;
    String username; 
    String message;

    public myServerSocketRunnable(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            while(true) {
                in =  new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                out = new PrintWriter(clientSocket.getOutputStream(), true);

                username = in.readLine();
                message = in.readLine();

                System.out.println(" "+username+": "+message);
                out.println(" "+username+": "+message);
                out.flush();
            }
        } catch(IOException aww) {
            System.out.println(" "+username+" has disconnected!");
            out.println(" "+username+" has disconnected!"); 
        } finally {
            try {
                in.close();
                out.close();
            } catch(IOException aww) {
                aww.printStackTrace();
            }
        }
    }

}




public class myServer {

    public static void main(String[] args) {

        myServerSocket call = new myServerSocket();

        System.out.println("=========================================");
        System.out.println("=             Messenger Server          =");
        System.out.println("=========================================");

        call.runServer();
    }
}

客户端

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
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.PrintWriter;
import java.net.Socket;


public class Messenger {
    private static String hostName = "127.0.0.1";
    private static int portNumber = 4434;
    private static Socket clientSocket;
    private static PrintWriter out;
    private static BufferedReader in;

    private static String username, content;
    private static JFrame firstFrame, secondFrame;
    private static JTextField userName, userField, clientTextField;
    private static JTextArea clientTexts;
    private static JButton talkButton, sendButton;


    public static void firstGUI(Container pane) {
        pane.setLayout(null);

        userName = new JTextField("Username :");
        userName.setBounds(10, 35, 70, 20);
        userName.setEditable(false);

        userField = new JTextField();
        userField.setBounds(10, 55, 225, 20);

        talkButton = new JButton("Talk!");
        talkButton.setBounds(85, 100, 70, 35);
        talkButton.setFont(new Font("Verdana", Font.PLAIN, 15));

        pane.add(userName);
        pane.add(userField);
        pane.add(talkButton);
        pane.setBackground(Color.DARK_GRAY);

        talkButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                username = userField.getText();
                showFrame();
                talkButton.setEnabled(false);
                firstFrame.dispose();
            }
        });

    }

    public static void showGUI() {

        firstFrame = new JFrame("Messenger");
        firstFrame.setVisible(true);
        firstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        firstFrame.setBounds(500, 100, 250, 200);
        firstFrame.setResizable(false);

        firstGUI(firstFrame.getContentPane());
    }

    public static void contentGUI(Container pane) {

        pane.setLayout(null);

        clientTexts = new JTextArea();
        clientTexts.setEditable(false);
        clientTexts.setBounds(15, 10, 465, 490);
        clientTexts.setBackground(Color.WHITE);
        clientTexts.setFont(new Font("Verdana", Font.PLAIN, 13));

        clientTextField = new JTextField();
        clientTextField.setText("");
        clientTextField.setBounds(15, 525, 360, 25);
        clientTextField.setBackground(Color.WHITE);
        clientTextField.setFont(new Font("Verdana", Font.PLAIN, 15));

        sendButton = new JButton("Send");
        sendButton.setBounds(405, 519, 75, 35);
        sendButton.setFont(new Font("Verdana", Font.PLAIN, 15));

        pane.add(clientTexts);
        pane.add(clientTextField);
        pane.add(sendButton);
        pane.setBackground(Color.DARK_GRAY);

        sendButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                content = clientTextField.getText();
                clientTextField.setText("");
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            out.println(username);
                            out.println(content);
                            out.flush();
                            clientTexts.append(in.readLine()+"\n");
                        } catch (IOException aww) {
                            aww.printStackTrace();
                        }
                    }
                }).start();

            }
        });
    }

    public static void showFrame() {

        secondFrame = new JFrame("Messenger - Client");
        secondFrame.setVisible(true);
        secondFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        contentGUI(secondFrame.getContentPane());

        secondFrame.setBounds(550, 100, 500, 600);
        secondFrame.setResizable(false);


    }

    public static void main(String[] args) {

        try {
            showGUI();
            clientSocket = new Socket(hostName, portNumber);
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        } catch(IOException aww) {
            userField.setForeground(Color.RED);
            userField.setFont(new Font("Courier new", Font.PLAIN, 13));
            userField.setText("Server is not Online");
            userField.setEditable(false);
            talkButton.setEnabled(false);

            aww.printStackTrace();
        }

    }

}

我想知道代码的哪一部分是错的。也许是解决问题的解决方案。

1 个答案:

答案 0 :(得分:1)

这里有一个问题:

clientSocket = serverSocket.accept();
myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
clients.add(client);
new Thread(new myServerSocketRunnable(clientSocket)).start();

您正在创建两个 myServerSocketRunnable对象,一个添加到客户端List,另一个放在一个线程中并运行,这可能是一个严重的问题。而是为两者创建一个:

clientSocket = serverSocket.accept();
myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
clients.add(client);

// new Thread(new myServerSocketRunnable(clientSocket)).start(); // NO
new Thread(client).start();     // YES

我不知道这是否是你问题的原因,但我知道这是不对的,需要修复。另外,正如我在评论中所说,这个while (true)循环不属于:

while(true) {
    serverSocket = new ServerSocket(portNumber);
}

只需创建一次服务器套接字然后继续。

此外,您的服务器将从一个客户端收到的数据广播到所有其他客户端?我会假设你会使用你的客户端ArrayList,但我没有看到这个被使用。客户端无法神奇地相互连接,服务器必须提供粘合剂。