У меня есть приложение клиент и сервер. Сервер отправляет файл по протоколу TCP, клиент принимает. Вот только после того как сервер отправил, клиент не может сделать десериализацию. Вот функция отправки файл.
public string SendFileName = null;
public void SendData()
{
// Состав отсылаемого универсального сообщения
// 1. Заголовок о следующим объектом класса подробной информации дальнейших байтов
// 2. Объект класса подробной информации о следующих байтах
// 3. Байты непосредственно готовых к записи в файл или для чего-то иного.
SendInfo si = new SendInfo();
// Если нет отсылаемого файла продолжать процедуру отправки нет смысла.
if (String.IsNullOrEmpty(SendFileName) == true) return;
if (SendFileName != null)
{
FileInfo fi = new FileInfo(SendFileName);
if (fi.Exists == true)
{
si.filesize = (int)fi.Length;
si.filename = fi.Name;
}
fi = null;
}
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, si);
ms.Position = 0;
byte[] infobuffer = new byte[ms.Length];
int r = ms.Read(infobuffer, 0, infobuffer.Length);
ms.Close();
byte[] header = GetHeader(infobuffer.Length);
byte[] total = new byte[header.Length + infobuffer.Length + si.filesize];
Buffer.BlockCopy(header, 0, total, 0, header.Length);
Buffer.BlockCopy(infobuffer, 0, total, header.Length, infobuffer.Length);
// Если путь файла указан, добавим его содержимое в отправляемый массив байтов
if (si.filesize > 0)
{
FileStream fs = new FileStream(SendFileName, FileMode.Open, FileAccess.Read);
fs.Read(total, header.Length + infobuffer.Length, si.filesize);
fs.Close();
fs = null;
}
try
{
// Отправим данные подключенным клиентам
NetworkStream ns = _tcpClient.tcpClient.GetStream();
// Так как данный метод вызывается в отдельном потоке рациональней использовать синхронный метод отправки
ns.Write(total, 0, total.Length);
// Обнулим все ссылки на многобайтные объекты и попробуем очистить память
header = null;
infobuffer = null;
total = null;
SendFileName = null;
GC.Collect();
GC.WaitForPendingFinalizers();
// Подтверждение успешной отправки
Parent.ShowReceiveMessage("Данные успешно отправлены!");
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Вот функция принятия файла на Клиентской стороне:
public void ReadCallback(IAsyncResult ar)
{
if (modeNetwork == Mode.indeterminately) return;
TcpClientData myTcpClient = (TcpClientData)ar.AsyncState;
try
{
NetworkStream ns = myTcpClient.tcpClient.GetStream();
int r = ns.EndRead(ar);
if (r > 0)
{
// Из главного заголовка получим размер массива байтов информационного объекта
string header = Encoding.Default.GetString(myTcpClient.buffer);
int leninfo = int.Parse(header);
// Получим и десериализуем объект с подробной информацией о содержании получаемого сетевого пакета
MemoryStream ms = new MemoryStream(leninfo);
byte[] temp = new byte[leninfo];
r = ns.Read(temp, 0, temp.Length);
ms.Write(temp, 0, r);
BinaryFormatter bf = new BinaryFormatter();
ms.Position = 0;
SendInfo sc = (SendInfo)bf.Deserialize(ms);
ms.Close();
if (sc.filesize > 0)
{
// Создадим файл на основе полученной информации и массива байтов следующих за объектом информации
FileStream fs = new FileStream(sc.filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, sc.filesize);
do
{
temp = new byte[global.MAXBUFFER];
r = ns.Read(temp, 0, temp.Length);
// Записываем строго столько байтов сколько прочтено методом Read()
fs.Write(temp, 0, r);
// Как только получены все байты файла, останавливаем цикл,
// иначе он заблокируется в ожидании новых сетевых данных
if (fs.Length == sc.filesize)
{
fs.Close();
fs = null;
break;
}
}
while (r > 0);
temp = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
if (Receive != null)
Receive(this, new ReceiveEventArgs(sc));
myTcpClient.buffer = new byte[global.LENGTHHEADER];
ns.BeginRead(myTcpClient.buffer, 0, myTcpClient.buffer.Length, new AsyncCallback(ReadCallback), myTcpClient);
}
else
{
DeleteClient(myTcpClient);
// Событие клиент отключился
if (Disconnected != null)
Disconnected.BeginInvoke(this, "Клиент отключился!", null, null);
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
DeleteClient(myTcpClient);
// Событие клиент отключился
if (Disconnected != null)
{
Disconnected.BeginInvoke(this, "Произошла ошибка во время обновления Базы Даных. Просьба повторить попытку.", null, null);
}
SoundError();
}
}
Вот это класс, который есть и на Клиенте и на Сервере:
[Serializable]
class SendInfo
{
public string message;
public string filename;
public int filesize;
}
Вот на этой строчке
SendInfo sc = (SendInfo)bf.Deserialize(ms);
и происходит ошибка, а именно пишет:
{"Не удалось привести тип объекта \"SERVER.SendInfo\" к типу \"KLIENT.SendInfo\"."} System.Exception {System.InvalidCastException}
Из ошибки видно, что вы пытаетесь привести объект одного типа, к объекту другого типа. Даже в случае, если классы имеют одинаковые поля и одинаковое название, это все равно разные классы.
Существует два варианта решения проблемы:
Ссылки по теме:
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите, как можно на c# редактировать таблицу? То есть, имеется xlsx файл с готовой таблицейИ на c# нужно как-то эту таблицу отредактировать...
Изучаю C# и WPFПодскажите пожалуйста какие темы необходимо прочитать для реализации удаленного обновления приложения у конечного пользователя
Подскажите пожалуйста, как исправить код ниже (c# winforms vs2010)Сейчас выдает ошибку "Не удалось загрузить файл Newtonsoft