Я пытаюсь создать Сервер (и, конечно, Клиента) для моей Игры.Он разработан с Java и не требует дополнительных библиотек или внешней работы.Соединение между клиентом и сервером в данный момент настроено так, что оно посылает определенное количество байтов (512) в виде «пакетов».Каждый пакет имеет идентификатор для своего типа (1 байт) и тело для своих данных (511 байт).В целом эта связь, кажется, работает.Проблема, с которой я сейчас сталкиваюсь, заключается в том, что когда я отправляю большое количество данных (карта ~ 10kb ~ 1300 пакетов) как можно быстрее, я, похоже, теряю сообщения или получаю сообщения с ошибкой (например, неправильный идентификатор пакета)).Я не могу понять, почему это происходит.Насколько я понимаю, сокеты в Java используют протокол TCP, который, насколько я знаю, должен предотвратить эти проблемы.
Это важная (на мой взгляд) часть сервера:
void sendToClient(Queue<DataPackage> packages) {
if(isConnected()){
try {
while(!packages.isEmpty()){
this.out.write(packages.get().getByteData());
packages.remove();
this.out.flush();
}
} catch (IOException e) {
e.printStackTrace();
if(!isConnected()){
if(!ended){
ended = true;
server.getServerManager().getEventManager().publishServerEvent(new ServerLostConnectionToClientEvent(id, connection));
}
}
}
}
}
Это важная (на мой взгляд) часть клиента:
private void acceptData() throws UnsupportedPackageException {
byte[] income = new byte[DataPackage.MAXPACKAGELENGTH];
try {
for(int length = in.read(income); length!=-1 && isConnected(); length = in.read(income)){
income = Arrays.copyOf(income, DataPackage.MAXPACKAGELENGTH);
DataPackage dataPackage = null;
try {
dataPackage = new DataPackage(income, length);
} catch (Exception ea) {ea.printStackTrace();}
if(dataPackage!=null){
if(!this.dataStreams.containsKey(dataPackage.getId())) this.dataStreams.put(dataPackage.getId(), new Queue<DataPackage>());
Queue<DataPackage> dataStream = dataStreams.get(dataPackage.getId());
if(dataPackage.isEnd()) {
this.dataStreams.remove(dataPackage.getId());
handNewDataPackage(dataPackage, dataStream);
}
}
income = new byte[DataPackage.MAXPACKAGELENGTH];
}
} catch (IOException e) {
e.printStackTrace();
if(this.client.run() && !ended){
this.client.endClient();
this.client.connectionLost(new ClientLostConnectionToServerEvent(this.socket));
}
ended = true;
}
}
Вот как я настраиваю соединение:
socket = new Socket(ip, port);
socket.setTcpNoDelay(false);
socket.setReceiveBufferSize(DataPackage.MAXPACKAGELENGTH);
socket.setSendBufferSize(DataPackage.MAXPACKAGELENGTH);
this.out = new BufferedOutputStream(socket.getOutputStream(), DataPackage.MAXPACKAGELENGTH);
this.in = new BufferedInputStream(socket.getInputStream(), DataPackage.MAXPACKAGELENGTH);
Вы можете просмотретьвесь проект (если хотите) здесь: https://github.com/reschiram/Game (новейшая ветвь: G-9)
Извините, если это выглядит так, это просто еще один дублирующий вопрос о том, как кодировать сокет Java.Я тоже видел несколько подобных вопросов здесь, но ни один из них не подходит для моей проблемы полностью (или не помог мне решить ее).