StreamCorruptedException во время создания настраиваемого Java-клиента
Я пытаюсь написать простой, но настраиваемый клиент на Java, но получаю странное исключение при выполнении тестов, а точнее при создании входного потока. Основная идея такова:
public class Client {
private String ipServer;
private int portNumber;
private Socket socket;
/** A flag value that indicates whenever {@code this} {@link Client} is connected to a <i>server</i>. */
private boolean clientIsActive = false;
/** It will acquire data sent from the <i>server</i> to the <i>client</i>. */
private ObjectInputStream streamIn = null;
/** It will send data from the <i>client</i> to the <i>server</i>. */
private ObjectOutputStream streamOut = null;
/** The instructions {@code this} {@link Client} will follow to communicate with the <i>server</i>. */
private Consumer<Client> communicationProtocol = null;
public Client(String ipServer, int portNumber, Consumer<Client> communicationProtocol) {
this.ipServer = ipServer;
this.portNumber = portNumber;
this.communicationProtocol = communicationProtocol;
}
}
После создания Client
класс не сразу подключается к серверу. Сначала необходимо выполнитьopenConnection()
метод: его цель - создать сокет, открыть потоки и начать выполнение инструкций.
public void openConnection() {
// Activates the socket and streams
try { this.socket = new Socket(ipServer, portNumber);
} catch (UnknownHostException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
try { this.streamIn = new ObjectInputStream(socket.getInputStream()); // THIS LINE CAUSES EXCEPTION ! ! !
} catch (IOException e) { e.printStackTrace(); }
try { this.streamOut = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) { e.printStackTrace(); }
this.clientIsActive = true;
// Starts communicating according to the specified communication protocol
this.communicationProtocol.accept(this);
}
Чтобы проверить, работает ли код, я использую следующий тест. Первый метод создает следующие инструкции:
- Клиент ждет первого сообщения от сервера и использует его в соответствии с
updateManager
, т.е. инструкция сообщения. - Первое сообщение затем используется
updateManager
, т.е. инструкция сообщения. В моем тесте это будет просто "распечатать полученную строку на консоль". - Если ожидается, что сервер отправит более одного обновления, и если полученное обновление не является
exitSignal
, клиент повторяет пункты 1. и 2. до тех пор, покаexitSignal
передается. - Когда клиент получает
exitSignal
, он закрывает соединение.
public static <T> Consumer<Client> serverSendsUpdatesToClients(Consumer<T> updateManager, T exitSignal, boolean sendsSingleUpdate){
return (Client client) -> {
T currentUpdate;
currentUpdate = client.receiveMessage();
updateManager.accept(currentUpdate);
if( currentUpdate != exitSignal && !sendsSingleUpdate )
do {
currentUpdate = client.receiveMessage();
updateManager.accept(currentUpdate);
} while( currentUpdate != exitSignal );
client.closeConnection();
};
}
Второй метод - это основной, который подключает клиента к серверу NIST. Конкретный используемый порт зарезервирован для службы запроса времени.
public static void main(String[] args) {
Consumer<String> stringManager = (String s) -> { System.out.println(s); };
Consumer<Client> instructions;
Client client = null;
instructions = CCPs.serverSendsUpdatesToClients(stringManager, "…", true);
client = new Client("time.nist.gov", 13, instructions);
client.openConnection();
}
Результат, который я ожидаю, будет примерно таким:
*58068 17-11-11 10:26:13 00 0 0 152.5 UTC(NIST) *
Вместо этого я получаю:
java.io.StreamCorruptedException: invalid stream header: 0A353838
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at client.Client.openConnection(Client.java:86)
at test.TestClient.main(TestClient.java:26)
Exception in thread "main" java.lang.NullPointerException
at client.Client.receiveMessage(Client.java:126)
at client.CCPs.lambda$0(CCPs.java:33)
at client.Client.openConnection(Client.java:93)
at test.TestClient.main(TestClient.java:26)
Исключение относится к входному потоку, который не создается. В чем проблема?