【问题标题】:Java error with a PrintWriter [duplicate]PrintWriter 的 Java 错误 [重复]
【发布时间】:2015-12-09 02:49:43
【问题描述】:

我有这段代码来连接服务器和客户端,我需要将 json 对象发送到 android studio 客户端,但是 printwriter 行中的方法 escribir 有错误,我不知道是什么问题,请参阅代码并帮助我

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();
}

还有这个

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);

        }

错误是

  java.lang.NullPointerException

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

我通过socket向客户端写入数据时出错,错误在getOutputStream中

【问题讨论】:

  • 谢谢我解决了问题

标签: java multithreading sockets server client


【解决方案1】:

socketnull,因为您没有设置它。

在尝试使用之前,您需要确保已创建套接字。

【讨论】:

  • 我可以改行 escritor= new PrintWriter(socket.getOutputStream()); by escritor=new PrintWriter(servidor.accept().getOutputStream(),true); ??
  • 参考我帖子中的最新编辑
  • @AdriánSánchez 如果您接受套接字并且不需要阅读它,则可以。你最好只在一个地方接受 Socket,否则你可能会造成混乱,因为你不知道哪个 accept() 会得到一个套接字连接。
【解决方案2】:

1) 一旦服务器套接字接受连接,就会为客户端创建新的套接字。

2) 现在将此套接字作为参数传递给 leer() 方法。不要将它作为成员变量存储在 Servidor 中。您必须在服务器端的许多套接字上进行操作。把这项工作留给 leer() 方法

下面的代码应该改成

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

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

并且您已经更改了 leer() 方法的签名以接受套接字作为参数:public void leer(Socket socket)

编辑:

3) 在对相关方法执行操作之前,请确保 Socket 在正确的状态下可用。您可以通过跨方法传递 Socket 来实现它,或者传递一些唯一的 Id,它可以检索 Socket。

例如如果将主类中的 Socket 替换为唯一字符串 Id (key) 和 Socket(value) 的 ConcurretnHashMap 并通过跨类和方法传递套接字 id 来检索套接字。

看看工作示例Socket programming

【讨论】:

  • 好建议,但请注意 leer 不会调用 escribir
  • 问题在于 Socket 中的 Servidor 变量。对于“N”个连接,您不能有单个 Socket 引用。您不知道该变量中保存了哪个套接字引用。一旦客户端连接关闭,该套接字将变为空
  • 我同意。套接字不应该是跨线程共享的变量。我怀疑 OP 需要简化他们的设计,以便它有更好的工作机会。
  • 将套接字从 leer 传递给 RegUser,从 RegUser 传递给 Servidor。你不会得到空指针异常。
  • 或者通过分配一个 id 将 Socket 更改为 ConcurrentHasMap 。跨类传递 id 并获取 Socket 引用并做任何你想做的事
猜你喜欢
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多