Мгновенная запись DataInputStream в socket

127
14 августа 2019, 00:40

Всех приветствую. Я пытаюсь сделать что-то вроде 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();
            }
        }
    }

}
Answer 1

Так как вы пишите данные мелкие кусками, стоит попробовать буферизированные потоки:

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();
READ ALSO
Как поместить в массив 10 000 000 000 чисел?

Как поместить в массив 10 000 000 000 чисел?

Мне нужно сделать массив в который я должна поместить 10 000 000 000 мелких чиселЯ дошла к тому что это не возможно

133
Is not assignable to Activity

Is not assignable to Activity

MusicAdapter Class

155
java оператор И в условии [закрыт]

java оператор И в условии [закрыт]

Как сделать так чтобы в if было несколько условийнапример

123