Всех приветствую. Я пытаюсь сделать что-то вроде real-time video streaming'a.
Появилась такая проблема:
Очень низкая скорость передачи данных client-server-client.
Если убрать из этой цепочки server (client-client via wifi) - то изображения передаются мгновенно, при этом в 15 fps.
Я подозреваю, что это из-за того, что я сначала ЧИТАЮ данные от одного клиента, а потом уже записываю их в сокет другого.
Можно ли как-то сразу записывать входящие данные?
Код:
public class ServerCom {
void MainMethod() throws IOException {
ServerSocket welcomeSocket = new ServerSocket(9191);
System.out.println("Server started");
Socket mSocket = welcomeSocket.accept();
System.out.println("First socket was connected");
mSocket.setKeepAlive(true);
Socket SECOND_SOCKET = welcomeSocket.accept();
System.out.println("Second socket was connected");
SECOND_SOCKET.setKeepAlive(true);
OutputStream os = SECOND_SOCKET.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
InputStream inStream = null;
inStream = mSocket.getInputStream();
DataInputStream is = new DataInputStream(inStream);
while (true) {
try {
// Смотрим, новое ли изображение
int token = is.readInt();
if (token == 4) {
dos.writeInt(4);
if (is.readUTF().equals("#@@#")) {
// если оно новое - отсылаем клиенту уведомление о том, что оно новое
dos.writeUTF("#@@#");
int imgLength = is.readInt();
// берем размер входящего изображения и отсылаем его на сокет 2-го клиента
dos.writeInt(imgLength);
// заканчиаем отсылвать размер, начинаем слать само изображение
dos.writeUTF("-@@-");
dos.flush();
byte[] buffer = new byte[imgLength];
int len = 0;
// записываем в буффер изображение
while (len < imgLength) {
len += is.read(buffer, len, imgLength - len);
}
// отправляем его
dos.write(buffer);
dos.flush();
System.out.println("Send to second socket");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Так как вы пишите данные мелкие кусками, стоит попробовать буферизированные потоки:
OutputStream os = SECOND_SOCKET.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
// теперь DataOutputStream будет писать в буферизированный стрим
DataOutputStream dos = new DataOutputStream(bos);
Как заметил @zRrr в комментах, вы читаете весь массив байт, а только потом пишете его в другой стрим. Можно сделать лучше. Вместо:
byte[] buffer = new byte[imgLength];
int len = 0;
// записываем в буффер изображение
while (len < imgLength) {
len += is.read(buffer, len, imgLength - len);
}
// отправляем его
dos.write(buffer);
dos.flush();
Вот так:
byte[] buffer = new byte[4096];
int len = 0;
while (len < imgLength) {
// прочитали кусок
int read = is.read(buffer, len, Math.min(imgLength - len, buffer.length));
// и сразу записываем его
dos.write(buffer, 0, read);
// не нужно здесь вызывать flush, вызовем его 1 раз в конце
len += read;
}
dos.flush();
Виртуальный выделенный сервер (VDS) становится отличным выбором
Мне нужно сделать массив в который я должна поместить 10 000 000 000 мелких чиселЯ дошла к тому что это не возможно