2016-08-06 3 views
0

Я использую функцию узла для компиляции буфера, состоящего из заголовка и полезной нагрузки. Первый член в заголовке - это общий размер буфера, который отправляется на сервер, второй элемент - это команда, которая отправляется на сервер, а затем полезная нагрузка добавляется в буфер. используя библиотеку bufferpack.js из NPM, когда я вычисляю длину требуемого буфера, я получаю тот же размер, что и после создания буфера, и возвращаю свойство длины буфера.Узел socket.write возвращает больше байтов, чем в исходном буфере

Проблема, которую я вижу, заключается в том, что после того, как буфер содержит более 127 байт, количество записанных байтов не соответствует количеству байтов в фактическом буфере, при тестировании я делал его 2 байта дольше. Это вызывает проблему на сервере, поскольку он не знает, что делать с дополнительными байтами.

Вот метод, который я использую, чтобы преобразовать данные в буфер, а затем отправить в буфер на сервер

_sendall(cmd, payload='', callback){ 
    console.log('payload:', payload.length) 
    let fmt = '>HB' 
    let size = struct.calcLength(fmt) + payload.length 
    console.log('size:',size) 
    let header = [size, cmd] 
    let buf = struct.pack(fmt, header) + payload 
    console.log('buf:', buf.length) 
    console.log('[INFO] Buffer Sent:',buf) 
    this.sock.write(buf, 'binary', (err)=>{ 
    console.log('[INFO] Bytes written now:', this.sock.bytesWritten-this._bytesWrittenPrevious) 
    console.log('[INFO] Total Bytes Written:', this.sock.bytesWritten) 
    this._bytesWrittenPrevious = this.sock.bytesWritten 
    if (err) { 
     console.log('[ERROR] _sendall:', err) 
     return callback(false) 
    } 
    return callback(true) 
    }) 
} 

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

[INFO] Sending the input setup 
payload: 20 
size: 23 
buf: 23 
[INFO] Buffer Sent: Iinput_int_register_0 
[INFO] Bytes written now: 23 
[INFO] Total Bytes Written: 143 

Вот что я вижу, когда система не работает должным образом, и сервер никогда не отвечает обратно и код вешает, как есть обратные вызовы, которые никогда не огнь.

[INFO] Sending the input setup 
payload: 143 
size: 146 
buf: 146 
[INFO] Buffer Sent: �Iinput_double_register_0,input_double_register_1,input_double_register_2,input_double_register_3,input_double_register_4,input_double_register_5 
[INFO] Bytes written now: 148 
[INFO] Total Bytes Written: 291 

Любые идеи о том, что происходит? Я не смог найти что-либо по поводу такой проблемы, поэтому любая помощь очень ценится.

UPDATE:

Я сделал изменения, рекомендованные @mscdex кодированию в sock.write и теперь я пишу такое же количество байтов, которые я посылаю, но я все еще имею вопрос. Я сузил его до элемента размера, который кодируется как unsigned short (H), используя библиотеку bufferpack.js. Anytime size больше 127 Я считаю, что его кодировка неверна, если я попытаюсь распаковать буфер, я получаю возвращаемое значение NaN для размера. Все еще работает над решением проблемы.

ответ

1

Когда вы отправляете двоичные данные, вы не хотите указывать 'utf8' как кодировку. Вы действительно должны использовать объекты Buffer вместо строк для двоичных данных. Однако, чтобы написать двоичную строку, вы можете использовать кодировку 'binary'. Это не позволит интерпретировать строку как UTF-8.

+0

Спасибо, что сделал размер байтов, записанных в настоящее время соответствует размеру буфера, который был построен. –

0

Я, наконец, смог заставить программу работать, перебирая библиотеку bufferpack.js для упаковки буфера. Похоже, что он не кодировал размер буфера, который отправлялся правильно, если размер буфера превышает 127 байтов. Значение H в переменной fmt должно было форматировать байт как знак без знака, похоже, ищет короткую подпись, но это всего лишь гипотеза в это время, пока я не успею в нее копаться дальше, так как я получил тот же результат, используя h который является подписанным коротким.

Чтобы решить проблему, я переключился на использование собственных методов записи буфера, и это решило проблему. Я посмотрю в bufferpack.js и посмотрю, смогу ли я найти проблему и разместить PR для репо, если я смогу ее исправить.

Вот новый код, который работает, как ожидалось:

_sendall(cmd, payload='', callback){ 
    let fmt = '>HB' 
    let size = struct.calcLength(fmt) + payload.length 
    let header = [size, cmd] 
    let buf = new Buffer(size) 
    buf.writeUInt16BE(size, 0) 
    buf.writeInt8(cmd, 2) 
    buf.write(payload.toString(), 3) 
    this.sock.write(buf, 'binary', (err)=>{ 
    console.log('[INFO] Bytes written now:', this.sock.bytesWritten-this._bytesWrittenPrevious) 
    console.log('[INFO] Total Bytes Written:', this.sock.bytesWritten) 
    this._bytesWrittenPrevious = this.sock.bytesWritten 
    if (err) { 
     console.log('[ERROR] _sendall:', err) 
     return callback(false) 
    } 
    return callback(true) 
    }) 
} 
+0

Если вы используете Буферы, вам вообще не нужен аргумент '' binary'' (это только для строк), просто: 'write (buf, (err) => {...})' – mscdex

Смежные вопросы