Ваш вопрос касается передачи байтовых массивов между клиентом и сервером в Java. Давайте разберем вашу проблему пошагово и предложим подход, который будет работать корректно.
### Проблема
Вы используете `PrintWriter` для отправки данных и `Scanner` для их получения. Однако `PrintWriter` и `Scanner` предназначены в первую очередь для работы со строками и текстом, а вы пытаетесь передавать и обрабатывать байтовые данные, что ведет к проблемам, таким как потеря данных или их неполучение.
### Решение
Чтобы правильно передать массив байтов, вам следует использовать потоки ввода и вывода байтов, такие как `DataOutputStream` и `DataInputStream`. Этот подход позволит вам передавать и получать массивы байтов и не потерять никаких данных.
#### Серверная часть
Вы можете изменить код сервера для использования `DataOutputStream`:
```java
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(1234)) {
while (true) {
Socket clientSocket = serverSocket.accept(); // ожидание подключения
try (DataOutputStream output = new DataOutputStream(clientSocket.getOutputStream())) {
MSPacket msgToClient = new MSPacket("Сервер", "Hello!!!", 0x01);
byte[] packetData = msgToClient.toPacket(); // Получите пакет в формате byte[]
output.writeInt(packetData.length); // Сначала отправляем длину пакета
output.write(packetData); // Затем отправляем сам пакет
output.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
#### Клиентская часть
Клиент также должен использовать `DataInputStream` для корректного чтения данных:
```java
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
public class MyClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 1234);
DataInputStream input = new DataInputStream(socket.getInputStream())) {
while (true) {
// Считываем длину сообщения
int length = input.readInt();
if (length > 0) {
byte[] message = new byte[length];
input.readFully(message); // Считываем все байты сообщения
MSPacket pct = MSPacket.parse(message);
System.out.println(new String(pct.senderName, StandardCharsets.UTF_8) +
new String(pct.msg, StandardCharsets.UTF_8));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
### Объяснение изменений
1. **Типы потоков**: Вместо `PrintWriter` и `Scanner` используются `DataOutputStream` и `DataInputStream` для работы с байтовыми массивами.
2. **Передача длины сообщения**: Перед тем как отправить массив байтов, сервер отправляет длину этого массива. Это поможет клиенту точно знать, сколько байтов следует прочитать.
3. **Чтение полного пакета**: На стороне клиента используется `readFully()` для считывания всего сообщения.
Теперь ваш код будет правильно обрабатывать и передавать массивы байтов, и вы избежите проблем, связанных с потерей данных или ошибками при чтении.