Java简单聊天客户端&服务器运行问题

时间:2014-07-17 18:32:23

标签: java .net io

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

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

Sourse Code:主要课程

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)

2 个答案:

答案 0 :(得分:0)

我希望能提供帮助,我会说你的代码中有一些错误,例如:

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

答案 1 :(得分:0)

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

可能有两个原因:

  1. 如果您没有手动呼叫.close(),即使您的程序已经终止,套接字也会继续运行。
  2. 该端口由另一个服务使用(例如web-server,database-server,...)

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

何时关闭套接字:
首先,我会向客户端和服务器添加方法shutdown()。在这些方法中,您只需关闭所有套接字实例,例如此处(您可能需要一些catch - 块):

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 - 块。