Java聊天客户端和服务器无法接收

时间:2014-11-24 01:47:13

标签: java

我正在为一个班级的聊天客户端工作并遇到一些我似乎无法找到的问题。在 ChatWindow EchoServer 中,所有系统打印行都正常工作,除了一个,它永远不会到达服务器响应"。每次尝试发送到服务器时,它都会跟随并正确打印出它应该发送的内容,但服务器永远不会收到任何内容。有没有人对我在这里遇到的事情有任何想法?请注意,我没有从编译器或运行时收到任何错误。

仍然是stackoverflow的新手,请告诉我是否可以添加任何内容以帮助您。

编辑1 :仍有相同的问题,但在EchoServer中添加了循环以修复服务器在连接到客户端后立即关闭的错误。

编辑2 :我发现套接字正在关闭我,这就是服务器断开连接的原因,我现在无法弄清楚为什么套接字可能正在关闭。我在 ChatWindow 构造函数中找到一个已关闭套接字的断点,在输入新创建的线程后立即执行。

编辑3 :进行了必要的修复,代码现在正常运行。

// Simple server to receive communication from a client on the same computer and echo it back
public class EchoServer {
    public static void main(String[] args) throws IOException {
       try (ServerSocket s = new ServerSocket(4688)) {
        // wait for client connection
          try (Socket incoming = s.accept()) {
             System.out.println("client connected");
             try (Scanner in = new Scanner(incoming.getInputStream())) {
                PrintWriter out = new PrintWriter(incoming.getOutputStream());
                out.println("Hello! Enter BYE to exit.");
                out.flush();

                System.out.println("sent message to client");

                // echo client input
                boolean done = false;
                while (true) {
                    while (!done && in.hasNextLine()) {
                       String line = in.nextLine();
                       System.out.println(line);
                       out.println("Echo: " + line);
                       out.flush();
                       if (line.trim().equals("BYE")) done = true;
                    }
                    if(done) break;
                }
            }
         }
      }
   }
}

// Client main class. runs next class
public class ChatProgram {
    public static void main(String[] args){
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new ChatWindow();
                    frame.setTitle("Chat Program");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(ChatProgram.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}



// accepts user input from a textField when button is pressed.
// gives it to the server and prints it in it's own textArea
// 
public class ChatWindow extends JFrame {
    private String username = "";
    private Scanner in;
    private PrintWriter out;
    private Socket s;
    public ChatWindow() throws IOException {
        initComponents(); // this initializes the gui
            try {
            s = new Socket("localhost", 4688);
            System.out.println("Connected to server");
            in = new Scanner(s.getInputStream());
            out = new PrintWriter(s.getOutputStream());
            class PollServer implements Runnable {
                @Override
                public void run(){
                    while(true){
                        if(in.hasNextLine()){
                            System.out.println("server responded");
                            String input = in.nextLine();
                            PrintToWindow(input);
                        } 
                    }
                }
            }
            catch(IOException io) {
            //I'll do something with this
            }
            Thread t1 = new Thread(new PollServer());
            t1.start();
        }
    }

    // Connect will be used later
    public void Connect() {
        SendToServer("connect " + username);
    }

    // Disconnect will be used later
    public void Disconnect() {
        SendToServer("Disconnect " + username);
    }

    // Handles all outbound messages to the server
    public void SendToServer(String clientOut) {
        out.println(clientOut);
        PrintToWindow(clientOut);
        System.out.println("sending to server: " + clientOut); // Program hits this and prints     correctly every time
        out.flush();
    }

    // Handles adding anything to the client's textArea. Will be implementing Synchronized later
    public void PrintToWindow(String clientIn) {
        textArea.append(clientIn + "\n");
    }
}

2 个答案:

答案 0 :(得分:0)

修正了问题。结果发生了什么只是因为我只是在构造函数中本地声明我的套接字。所以一旦构造函数完成,尽管我的全局“in”和“out”变量,套接字消失了。我修改了代码以包含更改,现在它正常工作

答案 1 :(得分:0)

很好,你已经解决了你的问题。在这里,我为您开发了一个可能对您有所帮助的简单方法。

客户等级

public class Client {

    Socket s;
    int port = 7777;
    DataOutputStream dos;
    DataInputStream dis;
    String IPAddress = "localhost";
    String title = "Client";

    public Client() {
        try {
            s = new Socket(IPAddress, port);
            dos = new DataOutputStream(s.getOutputStream());
            dis = new DataInputStream(s.getInputStream());
            new Window(title, dos, dis);
        } catch (Exception ex) {
        }
    }

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

服务器类

public class Server {

    ServerSocket ss;
    Socket s;
    int port = 7777;
    DataOutputStream dos;
    DataInputStream dis;
    String title = "Server";

    public Server() {
        try {
            ss = new ServerSocket(port);
            System.out.println("Server is listenning for incoming connection...");
            s = ss.accept();
            dos = new DataOutputStream(s.getOutputStream());
            dis = new DataInputStream(s.getInputStream());
            new Window(title, dos, dis);
        } catch (Exception ex) {
        }
    }

    public static void main(String[] args) {
        new Server();
    }
}

公共窗口类

public class Window extends JFrame {

    JTextArea display = new JTextArea();
    JScrollPane jsp = new JScrollPane(display);
    JTextField write = new JTextField();
    String msg;
    DataOutputStream dos;
    DataInputStream dis;

    public Window(String title, DataOutputStream dos, DataInputStream dis) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.dos = dos;
        this.dis = dis;
        add(jsp, BorderLayout.CENTER);
        add(write, BorderLayout.SOUTH);
        setTitle(title);
        setSize(300, 200);
        setVisible(true);
        write.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent ke) {
                if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
                    msg = write.getText();
                    write.setText("");
                    appendToDisplay(title + " : " + msg);
                    try {
                        dos.writeUTF(title + " : "+  msg);
                    } catch (Exception ex) {
                        System.out.println(ex.getMessage());
                        appendToDisplay("Cannot write to ...");
                    }
                }
            }
        });
        new Thread() {
            String msgRead;

            @Override
            public void run() {
                while (true) {
                    try {
                        msgRead = dis.readUTF();
                        appendToDisplay(msgRead);
                    } catch (Exception ex) {
                        System.out.println(ex.getMessage());
                        appendToDisplay("Sorry...");
                    }
                }
            }
        }.start();
    }

    public void appendToDisplay(String msg) {
        display.append(msg + "\n");
    }

    public static void main(String[] args) {

    }
}