Files
Web_CRICS_Server_VS2010_Prod/RCUHost/Implement/UpdateConfigReceiver.cs
2025-12-11 09:17:16 +08:00

143 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Common;
using Dao;
using Domain;
using RCUHost.Protocols;
namespace RCUHost.Implement
{
public class UpdateConfigReceiver : GenericReceiverBase, IUpdateConfigReceiver
{
private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(UpdateConfigReceiver));
private const int BLOCK_SIZE = 512; //TFTP块大小512字节
public void Update(HostUpdate hostUpdate, IList<Host> hosts)
{
if (hosts == null || hosts.Count == 0)
{
throw new ApplicationException("升级失败,没有找到需要升级的主机。");
}
if (String.IsNullOrEmpty(hostUpdate.Href))
{
throw new ApplicationException("升级失败,无效的配置文件。");
}
string updateFile = Tools.GetApplicationPath() + hostUpdate.Href;
if (!File.Exists(updateFile))
{
throw new ApplicationException("升级失败,【" + updateFile + "】不是有效的配置文件。");
}
FileInfo fileInfo = new FileInfo(updateFile);
ushort blockNum = (ushort)Math.Ceiling((double)fileInfo.Length / BLOCK_SIZE);
//升级配置文件
foreach (var host in hosts)
{
SendUpdateRequest(host, hostUpdate.Md5, blockNum);
//this.updateHostList.Add(new UpdateHostWorker(host, hostUpdate));
}
}
public override void Process(ReceiverContext context)
{
//base.Process(context);
//int startIndex = StructConverter.SizeOf(context.SystemHeader);
//UpdateConfigPacketReply? reply = DecodeUpdateConfigPacketReply(context.Data, startIndex);
//if (reply.HasValue)
//{
// logger.Error(string.Format("收到配置文件升级回复命令({0}:{1}{2}", context.RemoteEndPoint.Address.ToString(), context.RemoteEndPoint.Port, Tools.ByteToString(context.Data)));
// var updateHostWorker = updateHostList.FirstOrDefault(r => r.Host.HostNumber == context.SystemHeader.Value.HostNumber.ToString());
// if (updateHostWorker != null)
// {
// //主机升级后重启会发送回复搜索命令,这时更新版本号
// if (reply.Value.Status == UpdateHostPacketReply.Ready)
// {
// updateHostWorker.Update();
// }
// else
// {
// updateHostList.Remove(updateHostWorker);
// }
// }
//}
}
public override CommandType CommandType
{
get { return CommandType.UpdateConfig; }
}
#region Private Methods
/// <summary>
/// 发送升级指令到RCU主机
/// </summary>
/// <param name="host"></param>
/// <param name="updateFileMd5">升级文件MD5值</param>
public void SendUpdateRequest(Host host, string updateFileMd5, ushort blockNum)
{
byte[] data = CreateUpdateConfigRequestPacket(updateFileMd5, blockNum);
Send(data, host.HostNumber, host.MAC);// host.IP, host.Port);
}
/// <summary>
/// 创建升级配置数据请求数据包
/// </summary>
/// <param name="updateFileMd5">升级文件MD5值</param>
/// <param name="blockNum">块数量</param>
/// <returns></returns>
private byte[] CreateUpdateConfigRequestPacket(string updateFileMd5, ushort blockNum)
{
SystemHeader systemHeader = CreateSystemHeader();
int headerSize = StructConverter.SizeOf(systemHeader);
#if DEBUG
byte[] ipArr = IPAddress.Parse(Tools.GetLocalIP()).GetAddressBytes();
#else
byte[] ipArr = IPAddress.Parse(MessageIP).GetAddressBytes();
#endif
byte[] portArr = BitConverter.GetBytes((ushort)MessagePort);
uint[] md5Arr = Tools.MD5StringToUIntArray(updateFileMd5);
using (var stream = new MemoryStream())
{
stream.Seek(headerSize, SeekOrigin.Begin);
stream.Write(BitConverter.GetBytes(md5Arr[0]), 0, 4);
stream.Write(BitConverter.GetBytes(md5Arr[1]), 0, 4);
stream.Write(BitConverter.GetBytes(md5Arr[2]), 0, 4);
stream.Write(BitConverter.GetBytes(md5Arr[3]), 0, 4);
stream.Write(BitConverter.GetBytes(blockNum), 0, 2);
stream.Write(ipArr, 0, ipArr.Length);
stream.Write(portArr, 0, portArr.Length);
stream.Write(new byte[] { 0, 0 }, 0, 2);
//填充 SystemHeader
stream.Seek(0, SeekOrigin.Begin);
systemHeader.FrameLength = (ushort)stream.Length;
systemHeader.FrameNo = 0xFFFF;
byte[] headerData = StructConverter.StructToBytes(systemHeader);
stream.Write(headerData, 0, headerData.Length);
return stream.ToArray();
}
}
/// <summary>
/// 解码 UpdateHostPacketReply
/// </summary>
/// <param name="data"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
private UpdateConfigPacketReply? DecodeUpdateConfigPacketReply(byte[] data, int startIndex)
{
return StructConverter.BytesToStruct(data, startIndex, typeof(UpdateConfigPacketReply)) as UpdateConfigPacketReply?;
}
#endregion
}
}