Java error with a PrintWriter [duplicate]

2019-08-30 18:54发布

问题:

This question already has an answer here:

  • What is a NullPointerException, and how do I fix it? 12 answers

I have this code to connect a server with a client, i need send json objects to a android studio client but the method escribir in the line of the printwriter have a error, and i dont konw what is the problem, please see the code and help me

public class Servidor {
ServerSocket servidor=null;
Socket socket=null;
BufferedReader lector=null;
PrintWriter escritor=null;
Gson gson = new Gson();
public Servidor(){

}
public static void main(String[] args) {
    Servidor Server=new Servidor();
    Server.iniciarHilo();
}
public void iniciarHilo(){

Thread principal=new Thread(new Runnable(){
    public void run(){
        try{
        servidor=new ServerSocket(8080);
        while(true){
            socket=servidor.accept();
            leer();
        }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
});
principal.start();
System.out.println("Servidor iniciado......");
}
public void leer(){
    Thread leer_hilo=new Thread(new Runnable(){
    public void run(){
        RegUser registrar=new RegUser();
        try{
            lector=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while(true){
                JsonParser parser = new JsonParser();
                String mensaje= lector.readLine();
                JsonElement elemento = parser.parse(mensaje);
                String mensaje_in=elemento.getAsJsonObject().get("tipo").getAsString();
                if (lector==null){
                    System.out.println("Conexion Interrumpida....");
                }
                if (mensaje_in.equals("registrar")){
                    System.out.println("Solicitud de Registro");
                    registrar.newUser(elemento);
                }
                else if (mensaje_in.equals("ingresar")){
                    System.out.println("Solicitud de Ingreso");
                }


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

});
    leer_hilo.start();
}
public void escribir(final String dato){
    Thread escribir_hilo=new Thread(new Runnable(){
        public void run(){
            try{
                escritor= new PrintWriter(socket.getOutputStream());
                escritor.println(dato);
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    });
escribir_hilo.start();
}

And this

public class RegUser {
Gson gson = new Gson();
ListaEnlazada listaUsuarios;
Comparar comparar=new Comparar();
public RegUser(){

}
public void newUser(JsonElement elemento) throws IOException{
    Servidor respuesta=new Servidor();
    //respuesta=new Servidor();
    String user=elemento.getAsJsonObject().get("nombre").getAsString();
    //boolean result=comparar.UserComp(user);
    if(true){
        listaUsuarios=new ListaEnlazada();
        listaUsuarios.add(elemento);
        System.out.println(listaUsuarios.get(0)); 
        JsonObject o = new JsonObject();
        o.addProperty("tipo", String.valueOf("registro"));
        o.addProperty("estado", String.valueOf("completo"));
        String enviar_mensaje = gson.toJson(o);
        respuesta.escribir(enviar_mensaje);

        }

And the error is

  java.lang.NullPointerException

  at Servidor$3.run(Servidor.java:81)
  at java.lang.Thread.run(Thread.java:745)

I has an error when writing a data through the socket to the client, the error is in the getOutputStream

回答1:

The socket is null because you are not setting it.

You need to make sure the socket has been created before you attempt to use it.



回答2:

1) Once server socket accept the connection, new Socket is created for the client.

2) Now pass this socket to leer() method as parameter. Do not Store it in Servidor as member variable. You have to operate on many sockets on server side. Leave that job to leer() method

Below code should be changed from

socket=servidor.accept();
 leer();

to

 socket=servidor.accept();
 leer(socket);

and you have change signature of leer() method to accept socket as parameter : public void leer(Socket socket)

EDIT:

3) Make sure that Socket is available in right state to relevant method before you act on it. You can achieve it by passing Socket across methods Or pass some unique Id, which can retrieve the Socket.

e.g. If you replace Socket in main class with ConcurretnHashMap of Unique String Id (key) and Socket(value) and retrieve the socket by passing socket id across classes and methods.

Have a look working example Socket programming