Why my Java server close sockets?

2019-01-28 12:29发布

问题:

I have server and client. My server acepts all connections and returns to client string. But when I try to send more lines its crashed with

java.net.SocketException: Socket is closed at java.net.Socket.getOutputStream(Unknown Source) at server.ServerCore.hiMsg(ServerCore.java:67) at server.ServerCore.run(ServerCore.java:49)

Here is it my Server Code :

package server;

import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author pisio
 */
public class ServerCore extends Thread {

    private LoadSettings loadSettings = LoadSettings.Init();
    private int port = loadSettings.getConfigInt("port");
    private int max_connections = loadSettings.getConfigInt("max_connections");
    private String ipServer = loadSettings.getConfig("ipServer");
    private ServerSocket socket;
    private Socket connection;
    private boolean serverRuning = false;
    private int connectedUsers = 0;
    private Vector connVector = new Vector();

    @Override
    public void run() {

        try {
            socket = new ServerSocket(port, max_connections);
            System.out.println("+++\t Server was started at  address:" + socket.getLocalSocketAddress() + " with posible max users " + max_connections);

            serverRuning = true;

            while (serverRuning) {
                if (connectedUsers <= max_connections) {
                    connection = socket.accept();
                    connection.setKeepAlive(serverRuning);
                    connVector.add(connection);
                    connectedUsers = connVector.size();
                    hiMsg();
                    hiMsg();
                    hiMsg();

                }

                System.out.println("+++\t Last User:" + connVector.get(connVector.size() - 1).toString());
            }


        } catch (IOException ex) {
            //   Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void hiMsg() {

        try {
            Socket c = (Socket) connVector.get(connVector.size() - 1);
            PrintWriter out = new PrintWriter(new OutputStreamWriter(c.getOutputStream()));
            out.write("Hi user !  Im server !  Your master !  Blow me down\nping: ?  PONG ?");
            out.close();

        } catch (IOException ex) {
            Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void stopServer() {
        statusServer();
        serverRuning = false;
        try {
            socket.close();
        } catch (IOException ex) {
            //Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("+++++\t  SERVER WAS STOPED !");
        // System.exit(port);

    }

    public void statusServer() {
        if (serverRuning) {
            System.out.println("Server running at port:" + port + "  with connected users :" + connectedUsers + "/" + max_connections);
        } else {
            System.out.println("Server IS NOT RUNNING!");
        }
    }
}

And Here is it my client code :

package meetingsclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ServerConnect {

    private static ServerConnect sc = null;
    private Socket socket = null;

    private ServerConnect() {

        try {
            socket = new Socket("localhost", 8080);

            sendHiMsg();

        } catch (Exception ex) {
            Logger.getLogger(ServerConnect.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void sendHiMsg() throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));


        System.out.println("Input:" + in.readLine());


    }

    public static ServerConnect Init() {
        if (sc == null) {
            sc = new ServerConnect();
        }
        return ServerConnect.sc;
    }
}

I readed this topic : Socket Exception: socket is closed but this dotn helped me. // Sorry for the links , but I cant understand how properly to format my code here.

回答1:

From the javadoc of getOutputStream() in Socket:

Closing the returned OutputStream will close the associated socket.

Also, closing a PrintWriter (and all other Printers/Writers) close their underlying streams as well. So, you are closing your OutputStream by closing the PrintWriter (in hiMsg()) and then trying to write to the socket, which was closed.

To fix the problem, don't close the PrintWriter. Garbage collection will take care of it for you! But do close the socket when you are done with it.