Java - адрес уже используется (net bind) - PullRequest
0 голосов
/ 06 июля 2018

Я знаю, что этот вопрос задавали миллион раз, но я не нашел ситуации, подобной моей. У меня есть простое приложение чата в Java, которое работало несколько месяцев назад, и я вернулся к нему, и теперь у меня проблемы. Когда я запускаю свой server.java в eclipse, все работает нормально. Когда я запускаю файл client.java впоследствии, я получаю следующее:

Exception in thread "main" java.net.BindException: Address already in use: NET_Bind
    at java.base/java.net.DualStackPlainSocketImpl.bind0(Native Method)
    at java.base/java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
    at java.base/java.net.AbstractPlainSocketImpl.bind(Unknown Source)
    at java.base/java.net.PlainSocketImpl.bind(Unknown Source)
    at java.base/java.net.ServerSocket.bind(Unknown Source)
    at java.base/java.net.ServerSocket.<init>(Unknown Source)
    at java.base/java.net.ServerSocket.<init>(Unknown Source)
    at chat.Server.main(Server.java:18)

Я прекратил все запуски в eclipse, нашел PID в командной строке и убил его, попытался изменить номера портов, и я по-прежнему получаю адрес, который все еще используется, каждый раз, когда я пытаюсь запустить свои программы. Я также попытался запустить команду netstat -a в командной строке, чтобы найти используемые номера портов, ни один из которых не был тем, который я пробовал.

Server.java (содержит код сервера, а также класс обработчика клиента):

public class Server 
{
    //vector to store active clients, static so threads share the vector of clients
    static Vector<ClientHandler> activeUsers = new Vector<>();

    public static void main(String[] args) throws IOException 
    {
        ServerSocket serverSocket = new ServerSocket(1234); //server is listening on port 1234
        Socket s;   
        while (true) //infinite loop for getting client request
        {
            s = serverSocket.accept(); //accept the incoming request

            //obtain input and output streams
            DataInputStream dis = new DataInputStream(s.getInputStream());
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());

            String username = dis.readUTF(); //username is first thing sent from the client for naming
            ClientHandler newClient = new ClientHandler(s,username , dis, dos); //create a new handler object for handling this client

            //notify currently connected users that a new user has joined
            newClient.notifyUsers(activeUsers, " has joined the server!");

            Thread t = new Thread(newClient); //create a new Thread with this object.
            activeUsers.add(newClient); //add this client to active clients list
            t.start(); //start the thread.
        }//end while


    }//end main
}//end class Server

class ClientHandler implements Runnable 
{
    private String name;
    DataInputStream dis;
    DataOutputStream dos;
    Socket socket;
    boolean isloggedin;


    public ClientHandler(Socket socket, String name, DataInputStream dis, DataOutputStream dos) 
    {
        this.dis = dis; //data input stream
        this.dos = dos; //data output stream
        this.name = name; //client name
        this.socket = socket; //socket
        this.isloggedin=true; //handler is being created so user is logged in
    }
}

Client.java:

public class Client extends JFrame implements ActionListener
{
    DataInputStream dis = null;
    DataOutputStream dos = null;
    final static int ServerPort = 1234;
    JButton     sendMessage;
    JTextField  messageBox;
    JTextArea   chatBox;
    JButton     logoutButton;
    JButton     activeUsersButton;
    JFrame      newFrame    = new JFrame(".Chat");
    String username;
    Socket s = null;


    public Client(String user)
    {

        this.username = user;
    }

    public void start() throws UnknownHostException, IOException 
    {
        newFrame.setTitle("chat - " + username);

        InetAddress ip = InetAddress.getByName("localhost");

        //establish the connection to the server
        s = new Socket(ip, ServerPort);

        //obtaining input and out streams
        dis = new DataInputStream(s.getInputStream());
        dos =  new DataOutputStream(s.getOutputStream());

        dos.writeUTF(username);

        //readMessage thread
        Thread readMessage = new Thread(new Runnable() 
        {
            @Override
            public void run() 
            {
                while (dos != null && dis != null) {
                    try 
                    {
                        //read the message sent to this client
                        String msg = dis.readUTF();
                        System.out.println(msg);
                        chatBox.append(msg);
                    } //end try
                    catch (IOException e) 
                    {

                        e.printStackTrace();
                    }//end catch
                }//end while
            }//end run
        });
        display();
        readMessage.start();
    }


    //not sure what this needs to do? just to satisfy an error
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
         Object obj = e.getSource();
           if(obj == sendMessage){ 
                String msg = messageBox.getText();
                try {
                    dos.writeUTF(msg);
                    chatBox.append(username + ": " + msg + "\n"); //place what the user sent in the text box
                    messageBox.setText(""); 
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
           } 
           else{}
    }
}

Я пропустил код кнопки, так как она только отправляет / получает сообщения на сокетах, а также код пользовательского интерфейса.

1 Ответ

0 голосов
/ 06 июля 2018

Что-то уже прослушивается на порте 1234 при запуске вашего сервера: возможно, предыдущий экземпляр этого; или, возможно, в TIME_WAIT все еще есть сокет. Попробуйте это с SO_REUSEADDR, вот так:

ServerSocket serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(1234));

NB У вас есть другая проблема. Вы игнорируете конец потока. Учитывая, что вы звоните readUTF(), вам нужно поймать EOFException, выйти из цикла и закрыть сокет, когда он брошен. EOS волшебным образом не делает входные или выходные потоки нулевыми.

...