NetworkStream, CryptoStream. Проблема сериализации.
От: ID_soft  
Дата: 18.03.07 20:46
Оценка:
Доброго времени суток всем.
Столкнулся с проблемой сериализации через CryptoStream который в свою очеред прикреплен к NetworkStream.
Сериализация проходит нормально, а вот десериализация не проходит(т.е. блокирует процесс так, какбудто данных не приходило). Данные получаются только при закрытии CryptoStream.
Поиском наткнулся на FlushFinalBlock(), но это не помогло.
Подскажите как сделать чтобы данные нормально получались клиентом без закрытия потока? Или всетаки придется каждый раз закрывать поток а потом создавать его заново?
Отправляющий код:

crReadStream = new CryptoStream( clientNetStream, RM.CreateDecryptor( ), CryptoStreamMode.Read );
crWriteStream = new CryptoStream( clientNetStream, RM.CreateEncryptor( ), CryptoStreamMode.Write );

// отсылаем информацию о клиенте
try {
    bf.Serialize( crWriteStream, UserInfo );
    crWriteStream.FlushFinalBlock( );
}
catch ( Exception Ex ) {
    return -1;
}




Принимающий код:



try {
    robj = bf.Deserialize( crReadStream ); // <-- Здесь просто ничего не происходит пока не закроется поток на передающей стороне
    if ( robj.GetType() != typeof(UserInformation) ) {
        return -1;
    }
}
catch ( Exception Ex) {
    return -1;
}
Re: NetworkStream, CryptoStream. Проблема сериализации.
От: Zugma  
Дата: 18.03.07 22:52
Оценка:
ID_> robj = bf.Deserialize( crReadStream ); // <-- Здесь просто ничего не происходит пока не закроется поток

Ну может быть попробовать 'поэтапно':
byte[] Buffer = ...
crReadStream.Read(Buffer...);
robj = bf.Deserialize( new MemoryStream(Buffer) );
Re[2]: NetworkStream, CryptoStream. Проблема сериализации.
От: ID_soft  
Дата: 19.03.07 06:34
Оценка:
Здравствуйте, Zugma, Вы писали:

ID_>> robj = bf.Deserialize( crReadStream ); // <-- Здесь просто ничего не происходит пока не закроется поток


Z>Ну может быть попробовать 'поэтапно':

Z>
Z>byte[] Buffer = ...
Z>crReadStream.Read(Buffer...);
Z>robj = bf.Deserialize( new MemoryStream(Buffer) );
Z>


Проблема в том, что Read(...) выполняется пока из потока не будет прочтено n байт. Мне нужно чтобы десериализция происходила в момент принятия объекта.
Пользуясь поисками я обнаружил, что проблема в блочном алгоритме RijndaelManaged, т.е пока блок полностью не сформируется, serialize не выполниться. Может тогда подскажите какой мз алгоритмов является поточным?
Re[3]: NetworkStream, CryptoStream. Проблема сериализации.
От: Zugma  
Дата: 19.03.07 10:16
Оценка:
ID_>Проблема в том, что Read(...) выполняется пока из потока не будет прочтено n байт. Мне нужно чтобы десериализция происходила в момент принятия объекта.
Я точно не знаю, как с криптостримами, но у нормальных потоков есть свойство Length. Так что, по идее, в метод Read можно попробовать передавать именно его.

ID_>Пользуясь поисками я обнаружил, что проблема в блочном алгоритме RijndaelManaged, т.е пока блок полностью не сформируется, serialize не выполниться.

Я так не думаю. У тебя в твоем коде была строка

crWriteStream.FlushFinalBlock();

Эта строка завершает все криптографические процедуры и отправляет поток на другую сторону, т.е. на приемной стороне у тебя уже лежит полностью сериализованный объект но в открытом потоке.... из-за этого и проблемы.

Еще кстати сейчас подумал... может вместо

robj = bf.Deserialize( crReadStream );

написать что-то типа
if (clientNetStream.DataAvailable) //только здесь должен быть блокирующий вызов
robj = bf.Deserialize( crReadStream );
Re[4]: NetworkStream, CryptoStream. Проблема сериализации.
От: ID_soft  
Дата: 19.03.07 12:41
Оценка:
Здравствуйте, Zugma, Вы писали:

Z>Еще кстати сейчас подумал... может вместо

robj = bf.Deserialize( crReadStream );

написать что-то типа

Z>
Z>if (clientNetStream.DataAvailable) //только здесь должен быть блокирующий вызов
Z>robj = bf.Deserialize( crReadStream ); 
Z>


Сейчас проверил: свойство DataAvailable у clientNetStream не после вызова Serializ() не после FlushFinalBlock() не устанавливается в true. Данные приходят только после Close().
Интересный момент: сериализация в NetworkStream работает как часы — у меня обмен открытыми ключами таким образом делается для RSA
Re[5]: NetworkStream, CryptoStream. Проблема сериализации.
От: Pavel M. Россия  
Дата: 19.03.07 13:48
Оценка:
Здравствуйте, ID_soft, Вы писали:

ID_>Здравствуйте, Zugma, Вы писали:


Z>>Еще кстати сейчас подумал... может вместо

robj = bf.Deserialize( crReadStream );

написать что-то типа

Z>>
Z>>if (clientNetStream.DataAvailable) //только здесь должен быть блокирующий вызов
Z>>robj = bf.Deserialize( crReadStream ); 
Z>>


ID_>Сейчас проверил: свойство DataAvailable у clientNetStream не после вызова Serializ() не после FlushFinalBlock() не устанавливается в true. Данные приходят только после Close().

ID_>Интересный момент: сериализация в NetworkStream работает как часы — у меня обмен открытыми ключами таким образом делается для RSA

я не с Нетворк стримом работал, просто с Крипто. Тоже намучался. У меня в Using все было обернуто, но пока Close сделал ручками (и для верности FlushFinalBlock) все косячило, насколько я помню — давно было.
--------------------------
less think — do more
Re[5]: NetworkStream, CryptoStream. Проблема сериализации.
От: ID_soft  
Дата: 19.03.07 13:51
Оценка:
Все, разобрался. Если интересно, то проблема была в Padding(ака заполнение того самого последнего блока). По умолчанию включемо PCKS7. У меня нормально заработало только при Zeros(почему не понятно).
Спасибо всем кто принимал участие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.