【问题标题】:PrintWriter is null in java ServerJava Server 中的 PrintWriter 为空
【发布时间】:2022-01-18 20:28:09
【问题描述】:

我在为 java 中的机器人设置服务器 - 客户端连接时遇到问题。 我有两个客户端监听两个不同的端口。当服务器发送错误时,PrintWriter 为空。

也许这些方法在两个不同的实例中。但是我该如何解决呢?

服务器代码:


import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class Server {

    // port for the TCP/IP network
    private static int port = 30001;
    public void setPort(int newPort) {
        port = newPort;
    }
    private ServerSocket serverSocket;
    private Socket socket;

    private PrintWriter pw;

    public void start() throws IOException {
        System.out.println("Server: Hi, I am ready to serve you!");
        System.out.println("Server: Trying to connect.");
    
        // get a connection
        try {
            serverSocket = new ServerSocket(port);
            socket = serverSocket.accept();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Server: I got a connection!");

        pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
    }

    public void sendString(String msg) {
        pw.println(msg);
        pw.flush(); 
    }

    public void stop() throws IOException {
        pw.close();
        socket.close();
        serverSocket.close();
        System.out.println("Server has stopped");
    }
}

协调类代码:

package ServerV4Test;

import java.io.IOException;

public class CoordinateServer {
    
    private Server myServer01 = new Server();
    private Server myServer02 = new Server();
    
    public void sendString(String msg) {
                    myServer01.sendString(msg);
                    myServer02.sendString(msg);
    }

    public void startServerMaster () throws IOException {
        System.out.println("The server coordinator started!");
        
                Server myServer01 = new Server();
                
                myServer01.setPort(30001);
                myServer01.start();
                
                Server myServer02 = new Server();

                myServer02.setPort(30002);
                myServer02.start();
    }
}

程序代码:


import java.io.IOException;

public class ProgramServer {
        
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        CoordinateServer coordServer = new CoordinateServer();
        coordServer.startServerMaster();


            String sendString = "hello world";
    
            coordServer.sendString(sendString);
            
            coordServer.closeServerMaster();
    }
}

错误信息:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.io.PrintWriter.println(String)" because "this.pw" is null
    at ServerV4Test.Server.sendString(Server.java:40)
    at ServerV4Test.CoordinateServer.sendString(CoordinateServer.java:11)
    at ServerV4Test.ProgramServer.main(ProgramServer.java:16)

客户端代码:

import java.io.*;

import java.net.*;
import java.util.ArrayList;

public class Client {

    // set port and IP for the server
    private String hostname =  "localhost"; 
    private int port;
    public void setHostname (String sHost) {
        hostname = sHost;
    }
    public void setPort(int sPort) {
        port = sPort;
    }
    private InetSocketAddress address;
    private void createAddress() {
        address = new InetSocketAddress(hostname, port);
    }

    // create a list for the received strings
    private ArrayList<String> receivedList= new ArrayList<String>();

    public String getReceivedString() {
        String temp = receivedList.get(0); 
        receivedList.remove(0);
        return temp;
    }

    public boolean hasReceivedString() throws IOException {
        receiveString();
        if (receivedList.size() > 0) { 
            return true;
        }
        else {
            return false;
        }
    }

    private Socket socket;
    private BufferedReader bufReader;

    public void start() throws IOException {
        System.out.println("Client: I start myself!");
        System.out.println("Client: creating connection!");

        socket = new Socket();
        createAddress();

        socket.connect(address);

        System.out.println("Client: I got a connection!");

        InputStreamReader iStreamReader = new InputStreamReader(socket.getInputStream());
        bufReader = new BufferedReader(iStreamReader);
    }

    private void receiveString() throws IOException {
        while (bufReader.ready()) {
            if(bufReader.ready()) {
                String message = bufReader.readLine();
                receivedList.add(message);
            }
        }
    }

    public void stop() throws IOException {
        bufReader.close();
        socket.close();
        System.out.println("Client has stopped");
    }
}

客户端程序:


import java.io.IOException;

public class ProgramUseClient1 {

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        System.out.println("client testprogram started");

        // create an instance of the server
        Client myClient = new Client();

        myClient.setPort(30001);

        // start client
        myClient.start();

        // repeat receiving and sending
        boolean progRunning = true;
        while(progRunning) {

            // test if something is received
            if(myClient.hasReceivedString()) {
                String receivedString = myClient.getReceivedString();
                System.out.println("The client 1 received: " + receivedString);
                // test if client should be stopped
                myClient.stop();
                progRunning = false;
            }

        }
        System.out.println("Goodbye");
    }
}

【问题讨论】:

标签: java instance printwriter


【解决方案1】:

您创建了shadowed 变量myServer01myServer02,其中全局变量没有初始化PrintWriter pw。替换

Server myServer01 = new Server();

myServer01 = new Server();

myServer02 也是如此

【讨论】:

  • 我认为他还需要在 Server 构造函数中实例化打印编写器,并且在调用 Server#start() 之前不要延迟它。这种延迟并没有显着的好处,如果改变事件的顺序可能会导致更多的问题。
  • @hfontanez 用业务逻辑使构造函数负担过重,使得异常处理和代码测试变得困难
  • 有趣....我猜依赖注入对您来说“负担过重”?我从来没有听说过。初始化类使用的资源在我看来是构造函数的功能。
【解决方案2】:

一切都是关于事件的时间安排......

当您实例化 Server 对象时,全局变量 pw 为空。直到Server#start() 被调用,作者才被正确实例化。不幸的是,CoordiateServerServer 对象运行之前调用sendString(从未调用start())。

您没有理由需要延迟创建PrintWriter。确保它在 Server 构造函数中被实例化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-11
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 2016-06-05
    • 1970-01-01
    相关资源
    最近更新 更多