2014-10-16 2 views
0

Я не уверен, что «Буфер» - это то, что я ищу, поэтому я покажу вам свою проблему, и тогда вы, ребята, можете решить, правильно ли это слово и какое решение. В настоящее время я работаю над созданием сетевого порта для класса Java DataOutputStream в C#. Последнее, что мне нужно сделать, это исправить эту проблему с отправкой сегментированной информации.C# BinaryWriter буфер для отправки сегментов?

Вот мой WriteInt метод в C# (ClientOutput является экземпляром BinaryWriter)

public void WriteInt(int v) 
{ 
    ClientOutput.Write (((uint)v >> 24) & 0xFF); 
    ClientOutput.Write (((uint)v >> 16) & 0xFF); 
    ClientOutput.Write (((uint)v >> 8) & 0xFF); 
    ClientOutput.Write (((uint)v >> 0) & 0xFF); 
    IncCount (4); 
} 

Для тех, кто хочет сравнить; вот оригинал в Java

public final void writeInt(int v) throws IOException { 
     out.write((v >>> 24) & 0xFF); 
     out.write((v >>> 16) & 0xFF); 
     out.write((v >>> 8) & 0xFF); 
     out.write((v >>> 0) & 0xFF); 
     incCount(4); 
} 

нормально в Java вы бы назвать «Flush()» до того, как данные будут отправлены на сервер или клиент; Однако оказывается, что BinaryWriter автоматически смывает всякий раз, когда вы звоните «Write()»

Вот «ReadInt()» код в Java.

public final int readInt() throws IOException { 
     int ch1 = in.read(); 
     int ch2 = in.read(); 
     int ch3 = in.read(); 
     int ch4 = in.read(); 
     if ((ch1 | ch2 | ch3 | ch4) < 0) 
      throw new EOFException(); 
     return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); 
} 

Когда код Java выполняется на «WriteInt» и ReadInt называется на сервере, значение отображается правильно; Однако в настоящее время сервер обрабатывает целое число 4 раза и отображает целочисленное значение на основе сегментов.

Пример ввода (C#):

Client.WriteInt(1000); 

Пример вывода (Java):

0 
0 
50331648 
-402653184 

Когда на выходе должно быть:

1000 

Пожалуйста, потерпите меня, как я только что взял C# несколько дней назад, и я могу задавать глупый вопрос.

ответ

0

BinaryWriter имеет множество перегрузок метода Write(), и похоже, что вы вызываете перегрузку Write (Int32), которая, конечно же, отправляет четыре 4-байтовых целых числа.

Вы должны быть в состоянии решить эту проблему просто литьем свои значения байта в вызове Write():

public void WriteInt(int v) 
{ 
    ClientOutput.Write ((byte)(((uint)v >> 24) & 0xFF)); 
    ClientOutput.Write ((byte)(((uint)v >> 16) & 0xFF)); 
    ClientOutput.Write ((byte)(((uint)v >> 8) & 0xFF)); 
    ClientOutput.Write ((byte)(((uint)v >> 0) & 0xFF)); 
    IncCount (4); 
} 

Обратите внимание, что с технической точки зрения, вы не должны бросить значение V в UINT перед сменой. Даже если расширение знака должно было произойти, вы все равно маскируете все, кроме последнего байта. Но эта часть ничего не должна повредить.

Ознакомьтесь с версией BinaryWriter, поддерживаемой эндиансом Джона Скита. Там есть обсуждение и некоторые ссылки здесь: BinaryWriter Endian issue

+0

Единственная причина, по которой я перешел на 'uint', заключалась в том, что исходная библиотека, написанная в java, использовала сдвиги без знака. Я подумал, что есть причина для этого, поэтому я сохранил их методы.Я попробую это, когда вернусь домой и посмотрю, работает ли это. – Hobbyist

+0

Отлично работает, СПАСИБО! – Hobbyist

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