Ложится сервер
|
|
zisX | Дата: Среда, 06 Декабря 2017, 03:02 | Сообщение # 1 |
Neto Zis
Сейчас нет на сайте
| Есть сервак написан на c#, есть клиент написан на unity + c# Все построено на сокетах tcp И возникла небольшая проблема, если отправлять клиентом тестовый запрос (у меня его тип назван ping), серв его читает и отправляет ответ просто с типом реквеста и результатом допустим Ok = 0 Так вот если в структуру ответа отправлять только эти два поля, без кастомных с произвольным набором данных, то все окей, но если мы засунем в ответ инфу которая превышает 2k байт допустим, то на клиенте возникнет ошибка serializationexception unexpected binary element 0
Проверял по размеру отправляемых данных с сервера и принимаемых на клиенте оно одинаковое, десериализация у меня происходит вот так
Код public static T FromBytesJSON<T> (byte[] arrBytes) { return FromString<T>(FromBytes<string>(arrBytes)); }
public static T FromString<T> (string text) { return JsonConvert.DeserializeObject<T>(text , GetSettings()); }
public static T FromBytes<T> (byte[] arrBytes) { if (arrBytes == null || arrBytes.Length < 1) return default(T);
BinaryFormatter binForm = new BinaryFormatter(); T obj = (T)binForm.Deserialize(new MemoryStream(arrBytes));
return obj; }
Может ли проблема быть связана с тем что читаю я ответы и ивенты с сервера по такой схеме
1)буффер изначально равен 4 байт 2)читаю из потока информацию о количестве байт, которые мне нужно прочитать чтобы принять структуру DataInfo (она нужна чтобы узнать, что мне пришло ивент или респонс, а так же размер оного) 3)буфер равен полученному значению 4)получаю DataInfo 5)буфер равен значению DataInfo.Length, что равняется основной информации, которая передастся в следующий раз 6)буфер равен DataInfo.Length 7)получаю основную информацию разом
Сообщение отредактировал zisX - Среда, 06 Декабря 2017, 03:16 |
|
| |
drcrack | Дата: Среда, 06 Декабря 2017, 03:21 | Сообщение # 2 |
старожил
Сейчас нет на сайте
| BinaryFormatter несовместим даже между разными версиями .NET Framework, не говоря уже о Mono Если хочешь его использовать, у тебя на сервере должен быть точно такой же CLR как и на клиенте, а учитывая что в Unity используется древний как говно мамонта Mono, который как бы и не особо поддерживается после появления .NET Core, то проще отказаться от BinaryFormatter, чем терпеть устаревший на 5 лет язык еще и на сервере
Сообщение отредактировал drcrack - Среда, 06 Декабря 2017, 03:35 |
|
| |
zisX | Дата: Среда, 06 Декабря 2017, 03:56 | Сообщение # 3 |
Neto Zis
Сейчас нет на сайте
| drcrack, Ну сервак переписывать на другой язык уже не получиться слишком много обвеса, если только в будущем, как быть то тогда?
|
|
| |
drcrack | Дата: Среда, 06 Декабря 2017, 04:28 | Сообщение # 4 |
старожил
Сейчас нет на сайте
| Да не надо ничего переписывать, достаточно просто отказаться от BinaryFormatter и использовать что-то другое для сериализации Как временное решение можешь поставить на сервер точно такую же версию Mono как используется в клиенте
|
|
| |
zisX | Дата: Четверг, 07 Декабря 2017, 07:01 | Сообщение # 5 |
Neto Zis
Сейчас нет на сайте
| Исправил я проблему, если кому-то пригодится ее суть была такова: 1) Узнал сколько байт придет на основную информацию, я грузил ее разом примерно так stream.read(buffer, 0, size); 2) Массив приходил в не полном объеме, потому что остальная часть инфы еще не пришла, насколько я понял потому что tcp не гарантирует что данные придут такими же порциями, как и были отправлены, в частности у меня это было только при превышении 2к байт информации
Проблема решается вот таким приемом информации
Код private byte[] ReadStream (NetworkStream stream,int countBytesNeedReed) { int readSoFar = 0;
byte[] msg = new byte[countBytesNeedReed];
while (readSoFar < countBytesNeedReed) { var read = stream.Read(msg,readSoFar,msg.Length - readSoFar); readSoFar += read; if (read == 0) break; }
return msg; }
|
|
| |