【问题标题】:Java simple chat client & server Running ProblemsJava 简单聊天客户端和服务器运行问题
【发布时间】:2014-07-17 18:32:22
【问题描述】:

我正在为教育目的制作一个简单的 java 服务器和客户端,同时完成了 Java 语言的 Connections 章节的学习,并且在运行程序时遇到了一些问题,所以如果我能得到任何帮助我会很高兴解决我的问题,我在运行它时遇到了一个主要问题

问题:文本没有被双方发送,我已经创建了 2 个客户端,当我从客户端 1 向客户端 2 发送文本时,例如,一切都很好,但反之亦然

源代码:主类

public class Start {    
public static void main(String [] args) {

    chatserver server = new chatserver();
    server.go();

    chatclient chat = new chatclient();
    chat.go();

    chatclient2 chat2 = new chatclient2();
    chat2.go();

    }
}

第一个客户端类:

import java.io.*;

import java.net.*;

import java.util.*;

import javax.swing.*;


import java .awt.*;
import java.awt.event.*;


public class chatclient {
JTextArea incoming;
JTextField outgoing;
BufferedReader reader;
PrintWriter writer;
Socket sock;
public void go() {

    JFrame frame = new JFrame("Simple Chat Client V.1");

    JPanel mainPanel = new JPanel() ;
    incoming = new JTextArea(15,50);
    incoming.setLineWrap(true);
    incoming.setWrapStyleWord(true) ;
    incoming.setEditable(false);
    JScrollPane qScroller = new JScrollPane(incoming) ;
    qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

    outgoing = new JTextField(30);
    JButton sendButton = new JButton("Send");

    sendButton.addActionListener(new sendz());
    mainPanel.add (qScroller) ;
    mainPanel.add(outgoing);
    mainPanel.add(sendButton);
    connectinsetup();
    Thread thread = new Thread(new reader());
    thread.start();
    frame.getContentPane().add(BorderLayout.CENTER,mainPanel);
    frame.setSize(500,500);
    frame.setVisible(true);


}

public void connectinsetup() {
    try{
    Socket socket = new Socket("127.0.0.1",5000);
    InputStreamReader stream = new InputStreamReader(socket.getInputStream());      
    reader = new BufferedReader(stream);
    writer = new PrintWriter(socket.getOutputStream());
    System.out.println("Connection Established");
    }
catch(IOException ex) {
    ex.printStackTrace();
}   
}

public class sendz implements ActionListener {

    public void actionPerformed(ActionEvent arg0) {
        try{

            writer.println(outgoing.getText());
            writer.flush();

        }

        catch(Exception exz){
            exz.printStackTrace();
        }
    outgoing.setText("");
    outgoing.requestFocus();
    }

}

public class reader implements Runnable{

    public void run() {
String msg;
try{
while ( (msg = reader.readLine() ) != null) {

incoming.append(msg + "\n");

  }
}   

catch(Exception ex){
    ex.printStackTrace();
                   }    
                     }  
                                   }  


                                              }

服务器类:

import java.io.*;
import java.net.*;

public class chatserver {
    PrintWriter writer;

    public void go() {

        try{
            ServerSocket socket = new ServerSocket(5000);
        while(true) {   
        Socket serversocket = socket.accept();
        Thread thread  = new Thread(new clienthandler(serversocket));
        thread.start();
         writer = new PrintWriter(serversocket.getOutputStream());



                    }
        }
        catch (Exception ex) {
            ex.printStackTrace();
                              }

                        } // end go method

    public class clienthandler implements Runnable {
Socket sock;
BufferedReader reader;
        public clienthandler( Socket socks) {
            try{
            sock = socks;
            InputStreamReader stream = new InputStreamReader(socks.getInputStream());
            reader = new BufferedReader(stream);   
            }
        catch(IOException ex) {
            ex.printStackTrace();
                            }   
                                           }

        public void run() {

            String msg;
        try{
            while((msg = reader.readLine())!= null ) {

            tellall(msg);
            }   
           }
            catch(Exception ex) {
            ex.printStackTrace();   
                               }                                         

                         }

                                                      } //end clienthandler class

public void tellall(String text){

    String msgall = text;

    try{
    writer.println(msgall);
    writer.flush();
      }
    catch(Exception ex){
        ex.printStackTrace();
                       }

                                } //end tellall method




                                          }//end chatserver

这是我得到的例外:

java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at test.chatserver.go(chatserver.java:12)
at test.Start.main(Start.java:12)

【问题讨论】:

  • 请问您可以发布任何抛出的异常及其堆栈跟踪吗?
  • 当然,运行时我只在控制台上得到这行异常:at test.Start.main(Start.java:8)
  • 我能得到一些帮助吗?
  • 对不起,我需要完整的堆栈跟踪,该异常消息根本没有帮助
  • 我如何获得完整的堆栈跟踪先生?因为那是我在控制台上得到的唯一异常消息

标签: java .net io


【解决方案1】:

我希望对您有所帮助,我会说它在您的代码中有一些错误,例如:

chatclient chat = new chatclient();
chat.go();

chatclient2 chat2 = new chatclient2();
chat2.go();

你没有任何chatclient2,你应该这样做:

chatclient chat = new chatclient();
chat.go();

chatclient chat2 = new chatclient();
chat2.go();

否则,如果您不将服务器放在不同的线程中,应用程序将被冻结,因为它正在等待客户端连接(并且客户的开头如下)解决很简单:

    new Thread() {
        public void run() {
            chatserver server = new chatserver();
            server.go();
        }
    }.start();

并回答您为什么只有文本出现在其中一个客户端中的问题是因为当您在服务器上这样做时:

Socket serversocket = socket.accept();
Thread thread = new Thread(new clienthandler(serversocket));
thread.start();
writer = new PrintWriter(serversocket.getOutputStream());

每次客户端连接时,“writer”都会被最后一个客户端套接字覆盖(每个客户端都有自己的套接字,我们可以通过它与他通信)

您可以修复它,例如一组带有套接字的不同写入器 ..

您好,希望对您有所帮助=D

【讨论】:

  • 我快哭了男人,一个大感谢
【解决方案2】:

BindException 被抛出,因为端口已在使用中。

可能有两个原因:

  1. 如果您不手动调用.close(),即使您的程序已经终止,一个Socket 也会继续运行。
  2. 端口被另一个服务使用(例如 web-server、database-server,...)

我怀疑选项 1 是您的特定异常的原因。只需尝试另一个端口或手动终止 java-background-task,然后再次尝试运行您的程序(并正确关闭套接字)。

何时关闭套接字:
起初我会向客户端和服务器添加一个方法shutdown()。在这些方法中,您只需关闭您拥有的所有套接字实例,例如这里(尽管您可能需要一些 catch-blocks):

public void shutdown() {
    serverSocket.close();
    /* close other sockets here */   
}

然后您将WindowListener 添加到两个客户端GUI 并在windowClosing() 中执行:

public void windowClosing(WindowEvent evt) {
    client.shutdown();
}

要关闭服务器,您可以将以下代码添加到main-方法:

System.out.println("Press Enter to stop the server ...");
System.in.read(); // wait for an "Enter"-press in the console

server.shutdown();

当关闭一个连接的Socket时,连接的另一端可能会抛出一些异常。所以不要忘记在那里放置适当的catch-blocks。

【讨论】:

  • 谢谢哥们,我真的很感谢你的帮助:)))
猜你喜欢
  • 2016-11-07
  • 2016-05-29
  • 2016-04-09
  • 2017-07-06
  • 1970-01-01
  • 2018-08-08
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多