You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using HslCommunication.Core;
using HslCommunication.Core.Net;
namespace HslCommunication.Enthernet
{
/// <summary>
/// 用于服务器支持软件全自动更新升级的类
/// </summary>
public sealed class NetSoftUpdateServer : NetworkServerBase
{
#region Constructor
/// <summary>
/// 实例化一个对象
/// </summary>
/// <param name="updateExeFileName">更新程序的名称</param>
public NetSoftUpdateServer( string updateExeFileName = "软件自动更新.exe" )
{
this.updateExeFileName = updateExeFileName;
}
#endregion
#region Private Member
private string m_FilePath = @"C:\HslCommunication";
private string updateExeFileName; // 软件更新的声明
#endregion
/// <summary>
/// 系统升级时客户端所在的目录默认为C:\HslCommunication
/// </summary>
public string FileUpdatePath
{
get { return m_FilePath; }
set { m_FilePath = value; }
}
/// <summary>
/// 当接收到了新的请求的时候执行的操作
/// </summary>
/// <param name="socket">异步对象</param>
/// <param name="endPoint">终结点</param>
protected override void ThreadPoolLogin( Socket socket, IPEndPoint endPoint )
{
try
{
OperateResult<byte[]> receive = Receive( socket, 4 );
if (!receive.IsSuccess) return;
byte[] ReceiveByte = receive.Content;
int Protocol = BitConverter.ToInt32(ReceiveByte, 0);
if (Protocol == 0x1001 || Protocol == 0x1002)
{
// 安装系统和更新系统
if (Protocol == 0x1001)
{
LogNet?.WriteInfo(ToString(), StringResources.Language.SystemInstallOperater + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
}
else
{
LogNet?.WriteInfo( ToString( ), StringResources.Language.SystemUpdateOperater + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
}
if (Directory.Exists(FileUpdatePath))
{
string[] files = Directory.GetFiles(FileUpdatePath);
List<string> Files = new List<string>(files);
for (int i = Files.Count - 1; i >= 0; i--)
{
FileInfo finfo = new FileInfo(Files[i]);
if (finfo.Length > 200000000)
{
Files.RemoveAt(i);
}
if (Protocol == 0x1002)
{
if (finfo.Name == this.updateExeFileName)
{
Files.RemoveAt(i);
}
}
}
files = Files.ToArray();
socket.BeginReceive(new byte[4], 0, 4, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
socket.Send(BitConverter.GetBytes(files.Length));
for (int i = 0; i < files.Length; i++)
{
// 传送数据包含了本次数据大小,文件数据大小,文件名(带后缀)
FileInfo finfo = new FileInfo(files[i]);
string fileName = finfo.Name;
byte[] ByteName = Encoding.Unicode.GetBytes(fileName);
int First = 4 + 4 + ByteName.Length;
byte[] FirstSend = new byte[First];
FileStream fs = new FileStream(files[i], FileMode.Open, FileAccess.Read);
Array.Copy(BitConverter.GetBytes(First), 0, FirstSend, 0, 4);
Array.Copy(BitConverter.GetBytes((int)fs.Length), 0, FirstSend, 4, 4);
Array.Copy(ByteName, 0, FirstSend, 8, ByteName.Length);
socket.Send(FirstSend);
Thread.Sleep(10);
byte[] buffer = new byte[4096];
int sended = 0;
while (sended < fs.Length)
{
int count = fs.Read(buffer, 0, 4096);
socket.Send(buffer, 0, count, SocketFlags.None);
sended += count;
}
fs.Close();
fs.Dispose();
Thread.Sleep(20);
}
}
}
else
{
// 兼容原先版本的更新,新的验证方式无需理会
socket.Send(BitConverter.GetBytes(10000f));
Thread.Sleep(20);
socket?.Close();
}
}
catch (Exception ex)
{
Thread.Sleep(20);
socket?.Close();
LogNet?.WriteException( ToString( ), StringResources.Language.FileSendClientFailed, ex);
}
}
private void ReceiveCallBack(IAsyncResult ir)
{
if (ir.AsyncState is Socket socket)
{
try
{
socket.EndReceive(ir);
}
catch(Exception ex)
{
LogNet?.WriteException( ToString( ), ex);
}
finally
{
socket?.Close();
socket = null;
}
}
}
#region Object Override
/// <summary>
/// 返回表示当前对象的字符串
/// </summary>
/// <returns>字符串信息</returns>
public override string ToString( )
{
return "NetSoftUpdateServer";
}
#endregion
}
}