Задать вопрос
@Noortvel

Можно ли избавиться от «слипания» байтов при WriteAsync из TcpClient.GetStream()?

Есть объект TcpClient, выставлен NoDelay = true, пишу асинхронно в его поток массив 16 байт, но когда посылаю 2 массива почти подряд, то они слипаются и на другом конце при чтение получается 32 байта. Как это исправить?
byte[] b1 = GetSomeBytesLen16();
client.GetStream().WriteAsync(b1, 0, b1.Length);
SomeAction1();
SomeAction1();
byte[] b2 = GetSomeBytes2Len16();
client.GetStream().WriteAsync(b2, 0, b2.Length);

//Где то в колбеке от BeginRead
int count = client.GetStream().EndRead(ar);//count = 32
  • Вопрос задан
  • 164 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 2
begemot_sun
@begemot_sun
Программист в душе.
Никак. TCP - это труба байт. Вы должны самостоятельно разделять поток байт на пакеты.
Ответ написан
Комментировать
shai_hulud
@shai_hulud
TCP это поток байтов, какими порциями оно будет приходить вы почти не контролируете.

Если пишете пакеты по 16 байт, то и читайте по 16 байт.

var buffer = new byte[16];
var offset = 0;
var read = 0;
while(offset < buffer.Length && (read = stream.Read(buffer, offset, buffer.Length - offset)) > 0)
{
    offset += read;
}

if (offset < buffer.Length) {  /* EOS */ }


Но конечно эффективней читать чем-то кратным размеру пакета и сразу много пакетов.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@OwDafuq
Сделайте проще, создайте определенную структуру ваших данных. Но в самом начале выделите 4 байта под РАЗМЕР, например, у вас есть массив байт и 100 значений, запишите в начало потока 100 и на сервере/клиенте читайте ровно 100 байт, профит
Ответ написан
@cicatrix
было бы большой ошибкой думать
Группы данных должны разделяться. Как это сделать - ваша задача. Обычно используют символ (сигнатуру)-терминатор, например \0, если длина передаваемых данных заранее неизвестна, либо символ (сигнатуру) начала новых данных, вслед за которой обычно пересылается длина передаваемого блока.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы