Я делаю безопасную программу VOIP в java, и я решил использовать netty для просто моей сети. До сих пор это была самая большая стоимость времени для проекта. VOIP отлично работает на локальном хосте, но когда я иду на другой компьютер в сети, происходит что-то странное. Прямо сейчас есть только два пакета, 50 для чата и 51 для выборки голоса. Программа работает отлично для нескольких кадров, затем я получаю случайные номера пакетов и недопустимые размеры. Я не уверен, что является причиной этого ..Пакеты, поврежденные netty
Вот класс, который передает пакеты:
package com.io;
import com.gui.VoiceCallFrame;
import com.net.Session;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;
/**
* @author Colby
*/
public class VoiceTransmitHandler implements VoiceIOHandler {
public VoiceTransmitHandler(String name, Session remote) {
this.remote = remote;
VoiceCallFrame frame = new VoiceCallFrame(name, this);
frame.setVisible(true);
}
private Session remote;
private boolean running;
public void start() {
running = true;
new Thread() {
@Override
public void run() {
try {
AudioFormat format = new AudioFormat(16000.0f, 16, 1, true, true);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine microphone = (TargetDataLine) AudioSystem.getLine(info);
try {
microphone.open(format);
microphone.start();
byte[] buf = new byte[4000];
do {
int len = microphone.read(buf, 0, buf.length);
ByteBuf packet = ByteBufAllocator.DEFAULT.buffer();
packet.writeByte(51);
packet.writeShort(len);
packet.writeBytes(buf, 0, len);
System.out.println("Send: " + packet.readableBytes());
remote.writeTCP(packet);
} while (running);
} finally {
microphone.close();
}
} catch (LineUnavailableException e) {
running = false;
e.printStackTrace();
}
}
}.start();
}
public void stop() {
running = false;
}
}
Вот где пакеты декодируются:
@Override
public void readTCP(ByteBuf msg) {
if (opcode == -1) {
if (msg.readableBytes() < 3) {
return;
}
opcode = msg.readUnsignedByte();
length = msg.readUnsignedShort();
}
if (msg.readableBytes() < length) {
return;
}
byte[] data = new byte[length];
msg.readBytes(data);
try {
System.out.println("Packet received " + opcode + ":" + length);
switch(opcode) {
case 51://Voice received
if(vrh == null) {
vrh = new VoiceReceiveHandler(host.getHostAddress());
vrh.start();
}
vrh.playLater(data);
break;
}
} finally {
opcode = length = -1;
}
}
Где что называется из в моем ChannelInboundHandlerAdapter
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
session.readTCP((ByteBuf) msg);
}
Я не вижу, где мои пакеты могут быть запутаны u p вообще. Мне кажется, что я правильно их передаю и расшифровываю. Если есть еще какой-то соответствующий код, необходимо просто оставить сообщение.
делают 'msg.readBytes' всегда заполняет все массив или возвращает переменное количество байтов, например 'InputStream.read'? – immibis
Казалось бы, заполнить весь массив: «public abstract ByteBuf readBytes (byte [] dst) Передает данные этого буфера указанному адресату, начинающемуся с текущего считывателяIndex, и увеличивает значение readerIndex на количество переданных байтов (= dst . .length) Броски: IndexOutOfBoundsException - если dst.length больше this.readableBytes» – Colby
Просто добавить, вот вывод: Пакет получил 51: 4000 Пакет получил 51: 4000 Пакет получил 51: 4000 Полученный пакет 64: 576 – Colby