socket - java client server tcp ip



Java: come fermare un server(chiudere un socket) senza eccezioni? (1)

Ho aggiunto il pulsante START / STOP che dovrebbe avviare / arrestare il server. Ma il codice non funziona come voglio: la connessione non è chiusa

Questo perché stai chiudendo il ServerSocket , non un socket accettato.

e il codice va a IOException "THIS IS PROBLEM" (nella parte ServerLogic).

È normale. Niente di sbagliato qui.

Inoltre i client possono ancora contattare il server.

No, non possono. I clienti esistenti possono continuare a utilizzare le loro connessioni esistenti . Se vuoi chiudere quelli, chiudili.

Come chiudere correttamente la connessione senza eccezioni?

Basta chiuderli. Non puoi farlo senza incorrere in eccezioni nel caso generale, e non c'è motivo per cui tu debba volerlo. Potrebbe essere meglio per i thread di socket accettati utilizzare un timeout di lettura e chiudere e uscire dopo aver ottenuto un timeout di lettura, anziché interrompere immediatamente ogni connessione esistente. È possibile impostare un timeout breve, ad esempio 15 secondi, in modo che il pulsante STOP sia ragionevolmente reattivo.

Dovrei appena prima di chiudere il socket inviare a tutti i client alcuni messaggi con richiesta di chiusura o semplicemente chiudendo il socket sul server dovrebbe essere sufficiente?

La chiusura della presa è sufficiente. L'invio di un messaggio in più non aggiunge alcun valore. I client riceveranno le consuete indicazioni di fine flusso dalle loro letture o una IOException: connection reset nelle loro scritture.

Ho creato un server che consente di unire molti clienti.
Comunque ho un problema.
Ho aggiunto il pulsante START / STOP che dovrebbe avviare / arrestare il server. Ma il codice non funziona come voglio: la connessione non è chiusa e il codice va all'IOException "QUESTO È PROBLEMA" (nella parte ServerLogic).
Inoltre i client possono ancora contattare il server.

LOGIC SERVER

public class ServerLogic
{

private static ServerSocket m_sSocket;
private static Set<ServerSubscriber> m_subscriberList = new HashSet<ServerSubscriber>();
private static boolean m_isServerRun = false;

private static class ServerLogicHolder
{
    static final ServerLogic INSTANCE = new ServerLogic();
}


private ServerLogic()
{}


public static ServerLogic getServerLogic()
{
    return ServerLogicHolder.INSTANCE;
}


/**
 * It starts listening of incoming connections from the clients.
 * 
 * @param port
 */
public void startListening(int port)
{
    try
    {
        if (!m_isServerRun)
        {
            m_sSocket = new ServerSocket(port);
            K6s.getUiServerConsole().addLine(Config.LOG_START);
            m_isServerRun = true;
        }
        else
        {
            System.out.println(Config.LOG_ERROR1);
        }
    }
    catch (IOException e)
    {
        System.out.println(Config.LOG_ERROR1);
    }

    try
    {
        while (isServerRun())
        {
            new Thread(new ServerSubscriber(m_sSocket.accept(), K6s.getUiServerConsole())).start();
        }
    }
    catch (IOException e1)
    {
        /*
         java.net.SocketException: socket closed
         at java.net.DualStackPlainSocketImpl.accept0(Native Method)
         at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
         at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
         at java.net.PlainSocketImpl.accept(Unknown Source)
         at java.net.ServerSocket.implAccept(Unknown Source)
         at java.net.ServerSocket.accept(Unknown Source)
         at org.czarny.k6s.comm.ServerLogic.startListening(ServerLogic.java:69)
         at org.czarny.k6s.gui.K6s$2$1.run(K6s.java:138)
         at java.lang.Thread.run(Unknown Source)
        */
    }
}


/**
 * Just close server's socket.
 */
public void stopListening()
{
    if (m_isServerRun)
    {
        try
        {
            m_isServerRun = false;
            m_sSocket.close();
            m_sSocket = null;
        }
        catch (IOException e)
        {
            m_isServerRun = true;
            System.out.println(Config.LOG_ERROR4);
        }
    }
}


public HashSet<ServerSubscriber> getSubscriberList()
{
    return (HashSet<ServerSubscriber>) m_subscriberList;
}


public boolean isServerRun()
{
    return m_isServerRun;
}
}

ISCRIZIONE CLIENT (non è stato rimosso il codice necessario)

public class ServerSubscriber implements Runnable
{

private Socket m_socket;
private LogComponent m_serverConsole;
private PrintWriter m_outComm;

private String m_subscriberIP;
private String m_subscriberName;
private String m_subsctiberLogInfo;


ServerSubscriber(Socket socket, LogComponent serverConsole)
{
    m_socket = socket;
    m_serverConsole = serverConsole;
    try
    {
        m_outComm = new PrintWriter(socket.getOutputStream(), true);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    sendMessage(Config.MSG_HANDSHAKE);
}


/**
 * This method runs messages from this subscriber.
 */
public void run()
{
    String line;
    BufferedReader inComm = null;

    try
    {
        inComm = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
    }
    catch (IOException e)
    {
        m_serverConsole.addLine(Config.LOG_ERROR3);
    }

    while (ServerLogic.getServerLogic().isServerRun())
    {
        try
        {
            //do something here
    }
}
}

Pulsante che gestisce START / STOP

uiStart.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent arg0)
        {
            if (!ServerLogic.getServerLogic().isServerRun())
            {
                uiStart.setText(Config.GUI_BTN_STOP);
                new Thread(new Runnable()
                {
                    public void run()
                    {
                        try
                        {
                            ServerLogic.getServerLogic().startListening(Integer.parseInt(uiServerPort.getText()));
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
            else
            {
                ServerLogic.getServerLogic().stopListening();
                m_uiServerConsole.addLine(Config.LOG_STOP);
                uiStart.setText(Config.GUI_BTN_START);
            }
        }
    });

Cosa mi sono perso?
Come chiudere correttamente la connessione senza eccezioni?
Dovrei appena prima di chiudere il socket inviare a tutti i client alcuni messaggi con richiesta di chiusura o semplicemente chiudendo il socket sul server dovrebbe essere sufficiente?
Saluti.





ioexception