Как остановить непрерывное выполнение цикла while с тем же соединением - PullRequest
1 голос
/ 08 апреля 2019

Я делаю сервер для приложения чата на Java.

Цикл while должен подключаться к новым клиентам, но код продолжает повторно подключаться к первому клиенту даже после его подключения, что приводит к ошибке Bind Failed. Что я должен изменить?

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ServerM
{   
    public static void main(String args[])
    {
        while(true)
        {
            Listener l = new Listener();
            l.run();
        }
    }

}

class Listener implements Runnable
{
    static InetAddress arr[] = new InetAddress[10];
    static int i = 0;

    public void run()
    {

        try
        {
            ServerSocket ss = new ServerSocket(44444);
            System.out.println("Waiting...");
            Socket s = ss.accept();
            System.out.println("Connected!\n");

            DataInputStream din=new DataInputStream(s.getInputStream());
            String ip = din.readUTF();

            InetAddress addr = InetAddress.getByName(ip);

            for(int j=0; j<=i; j++)
            {
                if(arr[j] == addr)
                    return;
            }

            arr[i++] = addr;

            ChatThread c = new ChatThread(addr,s);//This creates a thread to allow communication with Client
            c.run();

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

Ответы [ 2 ]

0 голосов
/ 08 апреля 2019

Catch Exception - плохая практика.

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

Попробуйте переместить пользовательское исключение (MyException.class) на верхний уровень и обработать это исключение в классе ServerM в try..catch.И не забудьте закрыть сокет в блоке finally

ss.close();
s.close();
0 голосов
/ 08 апреля 2019

Ваша проблема в дизайне решения.Вы запускаете несколько экземпляров сокета сервера (и используете один и тот же порт, что заканчивается исключением) и используете этот поток для получения клиентских соединений, поэтому вы можете иметь только одно соединение.

Что выследует запустить поток для серверного сокета, который будет прослушивать все соединения, а затем запускать каждый экземпляр клиента (новый поток) в бесконечном цикле.

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

        Listener l = new Listener();
        l.run();

    }

}

class Listener implements Runnable
{
    static InetAddress arr[] = new InetAddress[10];
    static int i = 0;

    public void run()
    {

        try
        {
            ServerSocket ss = new ServerSocket(44444);
            System.out.println("Waiting...");
            while (true) {
                Socket s = ss.accept();
                ClientListener clientListener = new ClientListener(s);
                clientListener.run();
            }

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

class ClientListener implements Runnable {

    private Socket socket;

    public ClientListener(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        System.out.println("Connected!\n");

        DataInputStream din=new DataInputStream(s.getInputStream());
        String ip = din.readUTF();

        InetAddress addr = InetAddress.getByName(ip);

        for(int j=0; j<=i; j++)
        {
            if(arr[j] == addr)
                return;
        }

        arr[i++] = addr;

        ChatThread c = new ChatThread(addr,socket);
        c.run();
    }

}

Это необходимо сделать, потому что вынужен только один экземпляр ServerSocket для прослушивания новых соединений на определенном порту, а затем вам нужно [1..n] клиентских экземпляров для обработки каждого соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...