Почему потоки не рассматриваются как строки на стороне клиента - PullRequest
0 голосов
/ 19 февраля 2020

Я сделал простую серверную и клиентскую программу, в которой сервер читает данные из файла и отправляет клиенту через сокет TCP. Но данные, которые я получаю, находятся в объекте, а не в простой строке?

Итак почему я не могу видеть данные в виде открытого текста, как в моем data.txt файле.

Пояснение с примером будет приветствоваться.

Вот мой код: -

КОД СЕРВЕРА

const fs = require('fs');
const net = require('net');

const readableData = fs.createReadStream('data.txt', 'utf8');

const server = net.createServer(socket => {
    socket.on('data', chunk => {
        console.log(chunk.toString());
        socket.write(JSON.stringify(readableData));
    });

    socket.on('end', () => {
        console.log("done");
    })

    socket.on('close', () => {
        console.log("closed")
    })
});

server.listen(3000);

КОД КЛИЕНТА

const fs = require('fs');
const net = require('net');

const client = new net.Socket();

client.connect('3000', () => {
    console.log("connected");
    client.write("Server please send the data");
});


client.on('data', chunk => {
    console.log("Data recieved:" + chunk.toString());
});

client.on('finish', () => {
    console.log("Work completed");
})

client.on('close', () => {
    console.log("connection closed");
})

А вот мой файл data.txt, который содержит простые данные

Привет, клиент, как ты?

И вывод, который я получаю здесь: -

Data recieved:{"_readableState":{"objectMode":false,"highWaterMark":65536,"buffer":{"head":{"data":"Hello client how are you ?","next":null},"tail":{"data":"Hello client how are you ?","next":null},"length":1},"length":26,"pipes":null,"pipesCount":0,"flowing":null,"ended":true,"endEmitted":false,"reading":false,"sync":false,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"paused":true,"emitClose":false,"autoDestroy":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrain":0,"readingMore":false,"decoder":{"encoding":"utf8"},"encoding":"utf8"},"readable":true,"_events":{},"_eventsCount":1,"path":"data.txt","fd":35,"flags":"r","mode":438,"end":null,"autoClose":true,"bytesRead":26,"closed":false}

Вопрос, почему я выиграл невозможно увидеть данные в виде открытого текста на стороне клиента, как в файле data.txt.

1 Ответ

1 голос
/ 19 февраля 2020

Ваша переменная readableData содержит объект потока node.js. Вот что это за переменная. Он используется только в текущем экземпляре node.js, поэтому он не делает ничего полезного, пытаясь отправить этот объект потока клиенту.

Если вы хотите получить все данные из этого файла 'data.txt' У вас есть несколько вариантов.

  1. Вы можете просто прочитать весь файл в локальную переменную с помощью fs.readFile() и затем отправить все эти данные с помощью socket.write().

  2. Вы можете создать новый поток, присоединенный к файлу для каждого нового входящего запроса, а затем, когда данные поступают в readStream, вы можете отправлять их в сокет (это часто называют передачей одного потока в другой). Если вы используете серверные конструкции более высокого уровня, такие как http-сервер, они упрощают конвейерную обработку.

Вариант №1 будет выглядеть следующим образом:

const server = net.createServer(socket => {
    socket.on('data', chunk => {
        console.log(chunk.toString());
        fs.readFile('data.txt', 'utf8', (err, data) => {
            if (err) {
                 // insert error handling here
                 console.log(err);
            } else {
                 socket.write(data);
            }
        });
    });

    socket.on('end', () => {
        console.log("done");
    })

    socket.on('close', () => {
        console.log("closed")
    })
});

FYI, Вы также должны знать, что socket.on('data', chunk => {...}) может дать вам любой размер данных. Потоки TCP не дают никаких гарантий относительно доставки точно таких же порций данных в тех же порциях, в которых они были первоначально отправлены. Они будут приходить по порядку, но если вы отправили три порции по 1 Кб с другого конца, они могут появиться как три отдельных Куски 1k, они могут быть получены как один кусок 3k, или они могут прийти как целая куча гораздо меньших кусков. То, как они прибудут, часто будет зависеть от того, по каким промежуточным транспортным средствам и маршрутизаторам они должны были проехать, и были ли какие-либо исправимые проблемы во время этой передачи. Например, данные, отправленные по спутниковому соединению inte rnet, вероятно, будут поступать небольшими порциями, поскольку потребности транспорта разбивают его на более мелкие части.

Это означает, что при чтении любых данных через обычное соединение TCP обычно нужен какой-то протокол, чтобы читатель знал, когда он получил полный, значимый кусок, который он может обработать. Если данные представляют собой простой текст, это может быть простой протокол, поскольку каждое сообщение заканчивается символом перевода строки. Но если данные являются более сложными, то протокол, возможно, должен быть более сложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...