|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using NetLibrary.Network;
|
|
|
using System.Collections;
|
|
|
using System.Net.Sockets;
|
|
|
using System.Threading;
|
|
|
using System.Net;
|
|
|
using NetLibrary.Log;
|
|
|
using System.IO;
|
|
|
|
|
|
namespace NetLibrary.Network
|
|
|
{
|
|
|
#region 服务器Socket
|
|
|
public class SocketService
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 要监控的端口号
|
|
|
/// </summary>
|
|
|
public int Port { get; set; }
|
|
|
/// <summary>
|
|
|
/// 空闲超时自动断开或引发心跳包事件
|
|
|
/// </summary>
|
|
|
public int OutTime { get; set; }
|
|
|
/// <summary>
|
|
|
/// 重发等待默认30秒后重发
|
|
|
/// </summary>
|
|
|
public int RefshSecond { get; set; }
|
|
|
/// <summary>
|
|
|
/// 最大消息等待回包数量(滑动窗口)
|
|
|
/// </summary>
|
|
|
public int MaxWaitMsgNumber { get; set; }
|
|
|
public AddressFamily Family { get; set; }
|
|
|
public int MaxSendNumber { get; set; }
|
|
|
public int BufferSize { get; set; }
|
|
|
public bool OutMaxSendNumberCloseConnect { get; set; }
|
|
|
/// <summary>
|
|
|
/// 是否长连接(默认长连接)
|
|
|
/// </summary>
|
|
|
public bool IsLongConnect { get; set; }
|
|
|
/// <summary>
|
|
|
/// 是否启用发送线程
|
|
|
/// </summary>
|
|
|
public bool IsSendThread { get; set; }
|
|
|
/// <summary>
|
|
|
/// 数据读取到时发生
|
|
|
/// </summary>
|
|
|
public event Action<ServerConnection, DataEventArgs> ReceiveData;
|
|
|
/// <summary>
|
|
|
/// 连接完成时发生
|
|
|
/// </summary>
|
|
|
public event Action<ServerConnection> ConnectSocketComplete;
|
|
|
/// <summary>
|
|
|
/// 关闭时发生
|
|
|
/// </summary>
|
|
|
public event Action<ServerConnection> CloseSocketComplete;
|
|
|
/// <summary>
|
|
|
/// 心跳请求事件
|
|
|
/// </summary>
|
|
|
public event Action<ServerConnection> OutTimeHappen;
|
|
|
/// <summary>
|
|
|
/// 发送失败事件
|
|
|
/// </summary>
|
|
|
public event Action<SocketMessage> SendError;
|
|
|
public event Action<ServerConnection> ReadDataMessage;
|
|
|
|
|
|
|
|
|
|
|
|
TcpSocketListener socketListener = null;
|
|
|
public ServerConnectionPool ListUserSocket = new ServerConnectionPool();
|
|
|
private AutoResetEvent AutoReset = new AutoResetEvent(false);
|
|
|
public SocketArgsPool socketArgsPool = null;
|
|
|
//BufferPool bufferManager = null;
|
|
|
public bool IsRun = false;
|
|
|
|
|
|
|
|
|
public SocketService()
|
|
|
{
|
|
|
Family = AddressFamily.InterNetwork;
|
|
|
IsSendThread = false;
|
|
|
IsLongConnect = false;
|
|
|
OutTime = 180;
|
|
|
Port = 10000;
|
|
|
RefshSecond = 30;
|
|
|
MaxWaitMsgNumber = 10;
|
|
|
BufferSize = 1024;
|
|
|
OutMaxSendNumberCloseConnect = false;
|
|
|
}
|
|
|
#region 初始化缓存
|
|
|
public void Init()
|
|
|
{
|
|
|
//初始化数据接收缓存
|
|
|
//bufferManager = new BufferPool(MaxConnect * BuffSize, BuffSize);
|
|
|
//bufferManager.InitBuffer();
|
|
|
|
|
|
// 声明异步Socket
|
|
|
//SocketAsyncEventArgs readWriteEventArg;
|
|
|
|
|
|
//for (int i = 0; i < MaxConnect; i++)
|
|
|
//{
|
|
|
// //初始化异步Socket
|
|
|
// readWriteEventArg = new SocketAsyncEventArgs();
|
|
|
// // 设备接收数据缓存
|
|
|
// bufferManager.SetBuffer(readWriteEventArg);
|
|
|
// // 把异步Socket放入集合顶部
|
|
|
// socketArgsPool.CheckIn(readWriteEventArg);
|
|
|
//}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 开始监控
|
|
|
public void Start()
|
|
|
{
|
|
|
socketArgsPool = new SocketArgsPool();
|
|
|
socketListener = new TcpSocketListener(Family, IPAddress.Any, Port, 10);
|
|
|
socketListener.SocketConnected += socketListener_SocketConnected;
|
|
|
socketListener.Start();
|
|
|
RunWhileListUserSocket();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 结束监控
|
|
|
public void Stop()
|
|
|
{
|
|
|
IsRun = false;
|
|
|
AutoReset.Set();
|
|
|
socketListener.Stop();
|
|
|
while (true)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
model.Disconnect();
|
|
|
}
|
|
|
ListUserSocket.Clear();
|
|
|
System.GC.Collect();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 结束监控并且发送断开连接消息
|
|
|
public void Stop(byte[] bytes)
|
|
|
{
|
|
|
IsRun = false;
|
|
|
AutoReset.Set();
|
|
|
socketListener.Stop();
|
|
|
while (true)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (bytes != null && bytes.Length > 0) model.SendData(bytes, 0, bytes.Length);
|
|
|
model.Disconnect();
|
|
|
}
|
|
|
ListUserSocket.Clear();
|
|
|
System.GC.Collect();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 启动发送线程
|
|
|
void RunWhileListUserSocket()
|
|
|
{
|
|
|
if (this.IsSendThread == true)
|
|
|
{
|
|
|
Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket));
|
|
|
t1.Start();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket2));
|
|
|
t1.Start();
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭设备连接
|
|
|
public bool CloseDevice(string IpAddress)
|
|
|
{
|
|
|
bool bk = false;
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.IpAddress == IpAddress)
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return bk;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭设备连接
|
|
|
public bool CloseDevice2(string DeviceNo)
|
|
|
{
|
|
|
bool bk = false;
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.DeviceNo == DeviceNo)
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return bk;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭设备连接
|
|
|
public bool CloseDevice3(string DeviceNo, int Port)
|
|
|
{
|
|
|
bool bk = false;
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.DeviceNo == DeviceNo && model.Port == Port)
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return bk;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 接受连接请求
|
|
|
void socketListener_SocketConnected(object sender, SocketEventArgs e)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
e.Socket.SendBufferSize = 32 * 1024;
|
|
|
e.Socket.ReceiveBufferSize = 32 * 1024;
|
|
|
e.Socket.LingerState = new LingerOption(true, 0);
|
|
|
e.Socket.SendTimeout = 60000;
|
|
|
//SocketAsyncEventArgs args = socketArgsPool.CheckOut();
|
|
|
SocketAsyncEventArgs args = null;
|
|
|
if (args == null)
|
|
|
{
|
|
|
args = new SocketAsyncEventArgs();
|
|
|
byte[] buffer = new byte[BufferSize];
|
|
|
args.SetBuffer(buffer, 0, buffer.Length);
|
|
|
}
|
|
|
ServerConnection connection = null;
|
|
|
try
|
|
|
{
|
|
|
connection = new ServerConnection(e.Socket, args);
|
|
|
connection.DataReceived += DataReceived;
|
|
|
connection.CloseSocketed += Disconnected;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
e.Socket.Close();
|
|
|
//if (connection!=null) connection.Disconnect();
|
|
|
return;
|
|
|
}
|
|
|
ListUserSocket.CheckIn(connection);
|
|
|
if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(connection);
|
|
|
}
|
|
|
catch (Exception exx)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(exx.TargetSite.Name, exx.StackTrace, exx.Message);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
#region 读取消息
|
|
|
void DataReceived(ServerConnection sender, DataEventArgs e)
|
|
|
{
|
|
|
if (e.Data.Length == 0) return;
|
|
|
sender.PrevTime = DateTime.Now;
|
|
|
if (this.ReceiveData != null) this.ReceiveData(sender, e);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 对方关闭连接
|
|
|
void Disconnected(ServerConnection model, SocketAsyncEventArgs e)
|
|
|
{
|
|
|
if (model == null || model.Enabled == false)
|
|
|
{
|
|
|
if (model != null)
|
|
|
{
|
|
|
model.DataReceived -= DataReceived;
|
|
|
model.CloseSocketed -= Disconnected;
|
|
|
}
|
|
|
if (this.CloseSocketComplete != null) this.CloseSocketComplete(model);
|
|
|
e.Dispose();
|
|
|
e = null;
|
|
|
model = null;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 发送完成时
|
|
|
void connection_SendCompleted(ServerConnection model)
|
|
|
{
|
|
|
if (this.IsRun == true) ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 轮循连接列表
|
|
|
void WhileListUserSocket()
|
|
|
{
|
|
|
//bool IsRemoveMessage = false;
|
|
|
IsRun = true;
|
|
|
while (IsRun)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ServerConnection model = ListUserSocket.CheckOut();
|
|
|
if (model == null)
|
|
|
{
|
|
|
AutoReset.WaitOne(5000, false);
|
|
|
continue;
|
|
|
}
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.PrevTime.AddSeconds(this.OutTime) < DateTime.Now)
|
|
|
{
|
|
|
if (this.IsLongConnect == false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("服务器检测到" + model.DeviceNo + "无应答", "", "断开对方连接");
|
|
|
model.Disconnect();
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//如果是长连接引发,心跳事件
|
|
|
if (this.OutTimeHappen != null)
|
|
|
{
|
|
|
this.OutTimeHappen(model);
|
|
|
model.PrevTime = DateTime.Now;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//如果服务器是断开连接的,那么不读取主动发送的数据
|
|
|
if (string.IsNullOrEmpty(model.DeviceNo) == false && model.ListMessage.Count == 0)
|
|
|
{
|
|
|
if (this.ReadDataMessage != null) this.ReadDataMessage(model);
|
|
|
}
|
|
|
if (model.ListMessage.Count > 0)
|
|
|
{
|
|
|
while (model.WaitMsgNumber < this.MaxWaitMsgNumber)
|
|
|
{
|
|
|
SocketMessage Msg = model.GetNextSocketMessage(this.RefshSecond);
|
|
|
if (Msg == null) break;
|
|
|
if (this.MaxSendNumber > 0 && Msg.SendNumber > this.MaxSendNumber)
|
|
|
{
|
|
|
if (OutMaxSendNumberCloseConnect == false)
|
|
|
{
|
|
|
model.EndWaitMsg(Msg.SequenceID);
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (this.Send(model, Msg) == false)
|
|
|
{
|
|
|
if (this.SendError != null) this.SendError(Msg);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.ListMessage.IsEmployMessages == true) model.ListMessage.RemoveEmploy();
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
AutoReset.WaitOne(10, false);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 轮循连接列表
|
|
|
void WhileListUserSocket2()
|
|
|
{
|
|
|
IsRun = true;
|
|
|
while (IsRun)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ServerConnection model = ListUserSocket.CheckOut();
|
|
|
if (model == null)
|
|
|
{
|
|
|
AutoReset.WaitOne(30000, false);
|
|
|
continue;
|
|
|
}
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.PrevTime.AddSeconds(this.OutTime) < DateTime.Now)
|
|
|
{
|
|
|
if (this.IsLongConnect == false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("服务器检测到" + model.DeviceNo + "无应答", "", "断开对方连接");
|
|
|
model.Disconnect();
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//如果是长连接引发,心跳事件
|
|
|
if (this.OutTimeHappen != null)
|
|
|
{
|
|
|
this.OutTimeHappen(model);
|
|
|
model.PrevTime = DateTime.Now;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (model.Enabled == false) continue;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
AutoReset.WaitOne(100, false);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 发送数据
|
|
|
public bool Send(ServerConnection model, SocketMessage msg)
|
|
|
{
|
|
|
model.PrevTime = DateTime.Now;
|
|
|
try
|
|
|
{
|
|
|
msg.SendNumber++;
|
|
|
msg.SendTime = DateTime.Now;
|
|
|
bool bk = model.SendData(msg.Bytes, 0, msg.SendLength);
|
|
|
if (bk == false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("Send", "", "发送失败断开连接");
|
|
|
model.Disconnect();
|
|
|
return false;
|
|
|
}
|
|
|
if (msg.IsRevert == false)
|
|
|
{
|
|
|
EndWaitMsg(model, msg.SequenceID);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (msg.SendNumber > 1) model.IncrementWaitMsgNumber();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
model.Disconnect();
|
|
|
return false;
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 返回UserSocket
|
|
|
public ServerConnection GetUserSocket(string IpAddress)
|
|
|
{
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.IpAddress == IpAddress) return model;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 返回UserSocket
|
|
|
public ServerConnection GetUserSocket2(string DeviceNo)
|
|
|
{
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.DeviceNo == DeviceNo) return model;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 返回UserSocket
|
|
|
public ServerConnection GetUserSocket3(string DeviceNo, int Port)
|
|
|
{
|
|
|
int index = ListUserSocket.Available;
|
|
|
for (int i = 0; i < index; i++)
|
|
|
{
|
|
|
var model = ListUserSocket.CheckOut();
|
|
|
if (model == null) break;
|
|
|
if (model.Enabled == false) continue;
|
|
|
if (model.DeviceNo == DeviceNo && model.Port != Port) return model;
|
|
|
ListUserSocket.CheckIn(model);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 消除已回复消息
|
|
|
public int EndWaitMsg(ServerConnection model, string SequenceID)
|
|
|
{
|
|
|
SocketMessage msg = model.EndWaitMsg(SequenceID);
|
|
|
if (msg == null) return 0;
|
|
|
return msg.MessageID;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
#endregion
|
|
|
#region 客户端Socket
|
|
|
public class ClientSocket
|
|
|
{
|
|
|
public string IpAddress { get; set; }
|
|
|
public int Port { get; set; }
|
|
|
public ServerConnection UseSocket { get; set; }
|
|
|
public int RefshSecond { get; set; }
|
|
|
/// <summary>
|
|
|
/// 最大消息等待回复数量
|
|
|
/// </summary>
|
|
|
public int MaxWaitMsgNumber { get; set; }
|
|
|
/// <summary>
|
|
|
/// 超出多少秒没有数据通讯后连接自动断开
|
|
|
/// </summary>
|
|
|
public int OutTime { get; set; }
|
|
|
public int BuffSize { get; set; }
|
|
|
public int MaxSendNumber { get; set; }
|
|
|
public bool IsLongConnect { get; set; }
|
|
|
public bool IsLogin { get; set; }
|
|
|
|
|
|
public event Action<ServerConnection, DataEventArgs> ReceiveData;
|
|
|
public event Action<ServerConnection> ConnectSocketComplete;
|
|
|
public event Action<ServerConnection> CloseSocketComplete;
|
|
|
public event Action<string> ConnectSocketError;
|
|
|
public event Action<ServerConnection> OutTimeHappen;
|
|
|
public event Action<SocketMessage> SendError;
|
|
|
|
|
|
private AutoResetEvent AutoReset = new AutoResetEvent(false);
|
|
|
private bool IsRun = false;
|
|
|
private DateTime PrevTime = DateTime.Now;
|
|
|
private int CloseReConnectTime = 0;
|
|
|
|
|
|
|
|
|
public ClientSocket()
|
|
|
{
|
|
|
IsLongConnect = true;
|
|
|
IsLogin = false;
|
|
|
RefshSecond = 30;
|
|
|
MaxWaitMsgNumber = 16;
|
|
|
MaxSendNumber = 0;
|
|
|
OutTime = 180;
|
|
|
BuffSize = 32 * 1024;
|
|
|
UseSocket = new ServerConnection();
|
|
|
UseSocket.DataReceived += DataReceived;
|
|
|
UseSocket.CloseSocketed += Disconnected;
|
|
|
}
|
|
|
|
|
|
#region 开始监控
|
|
|
public void Start()
|
|
|
{
|
|
|
IsRun = true;
|
|
|
Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket));
|
|
|
t1.Name = "ClientSocket";
|
|
|
t1.Start();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 停止
|
|
|
public void Stop()
|
|
|
{
|
|
|
IsRun = false;
|
|
|
AutoReset.Set();
|
|
|
CloseSocket(UseSocket);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 连接
|
|
|
bool SocketAccept()
|
|
|
{
|
|
|
IPAddress broadcast = IPAddress.Parse(IpAddress);
|
|
|
IPEndPoint ep = new IPEndPoint(broadcast, Port);
|
|
|
Socket e = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
|
e.LingerState = new LingerOption(true, 0);
|
|
|
e.SendTimeout = 60000;
|
|
|
try
|
|
|
{
|
|
|
e.Connect(ep);
|
|
|
System.Threading.Thread.Sleep(1000);
|
|
|
UseSocket.PrevTime = DateTime.Now;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
CloseReConnectTime = 60;
|
|
|
ErrorFollow.TraceWrite("连接失败", this.IpAddress+":"+Port, ex.Message);
|
|
|
if (this.ConnectSocketError != null) this.ConnectSocketError(this.IpAddress);
|
|
|
return false;
|
|
|
}
|
|
|
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
|
|
|
byte[] bytes = new byte[this.BuffSize];
|
|
|
args.SetBuffer(bytes, 0, this.BuffSize);
|
|
|
|
|
|
UseSocket.Start(e, args);
|
|
|
if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(this.UseSocket);
|
|
|
return true;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 读取消息
|
|
|
void DataReceived(ServerConnection sender, DataEventArgs e)
|
|
|
{
|
|
|
if (e.Data.Length == 0) return;
|
|
|
UseSocket.PrevTime = DateTime.Now;
|
|
|
if (this.ReceiveData != null) this.ReceiveData(sender, e);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 对方关闭连接
|
|
|
void Disconnected(ServerConnection sender, SocketAsyncEventArgs e)
|
|
|
{
|
|
|
CloseReConnectTime = 60;
|
|
|
if (this.CloseSocketComplete != null) this.CloseSocketComplete(sender);
|
|
|
e.Dispose();
|
|
|
e = null;
|
|
|
//ErrorFollow.TraceWrite("TcpSocker.Disconnected", "", "对方关闭连接");
|
|
|
//CloseSocket(sender);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 轮循消息列表
|
|
|
void WhileListUserSocket()
|
|
|
{
|
|
|
bool bk = false;
|
|
|
//SocketAccept();
|
|
|
while (IsRun)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (UseSocket.Enabled == false)
|
|
|
{
|
|
|
if (this.IsLongConnect == true || UseSocket.ListMessage.Count > 0)
|
|
|
{
|
|
|
if (CloseReConnectTime > 0)
|
|
|
{
|
|
|
CloseReConnectTime = 0;
|
|
|
AutoReset.WaitOne(60000);
|
|
|
}
|
|
|
bk = SocketAccept();
|
|
|
if (bk == true) continue;
|
|
|
if (IsRun == true) AutoReset.WaitOne(60000);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (IsRun == true) AutoReset.WaitOne(2000, false);
|
|
|
}
|
|
|
continue;
|
|
|
}
|
|
|
if (UseSocket.PrevTime.AddSeconds(this.OutTime) < DateTime.Now)
|
|
|
{
|
|
|
if (this.IsLongConnect == false)
|
|
|
{
|
|
|
CloseSocket(UseSocket);
|
|
|
bk = true;
|
|
|
continue;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//如果是长连接引发,心跳事件
|
|
|
if (this.OutTimeHappen != null)
|
|
|
{
|
|
|
this.OutTimeHappen(UseSocket);
|
|
|
UseSocket.PrevTime = DateTime.Now;
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (UseSocket.ListMessage.Count > 0)
|
|
|
{
|
|
|
//ErrorFollow.TraceWrite("发送数据", "", "数量:" + UseSocket.ListMessage.Count + ",等待数:" + UseSocket.WaitMsgNumber);
|
|
|
while (true)
|
|
|
{
|
|
|
SocketMessage Msg = UseSocket.GetNextSocketMessage(this.RefshSecond);
|
|
|
if (Msg == null) break;
|
|
|
if (UseSocket.WaitMsgNumber >= this.MaxWaitMsgNumber) break;
|
|
|
if (this.MaxSendNumber > 0 && Msg.SendNumber > this.MaxSendNumber)
|
|
|
{
|
|
|
UseSocket.EndWaitMsg(Msg.SequenceID);
|
|
|
continue;
|
|
|
}
|
|
|
if (this.Send(UseSocket, Msg) == false)
|
|
|
{
|
|
|
if (this.SendError != null) this.SendError(Msg);
|
|
|
break;
|
|
|
}
|
|
|
UseSocket.IncrementWaitMsgNumber();
|
|
|
AutoReset.WaitOne(10, false);
|
|
|
}
|
|
|
}
|
|
|
if (IsRun == true) AutoReset.WaitOne(1000, false);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
CloseSocket(UseSocket);
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
#region 发送数据
|
|
|
public bool Send(ServerConnection model, SocketMessage msg)
|
|
|
{
|
|
|
model.PrevTime = DateTime.Now;
|
|
|
try
|
|
|
{
|
|
|
msg.SendNumber++;
|
|
|
msg.SendTime = DateTime.Now;
|
|
|
if (msg.SendNumber > 1)
|
|
|
{
|
|
|
string m = "第" + msg.SendNumber + "次";
|
|
|
m += ",上次发送时间:" + msg.SendTime;
|
|
|
m += ",id:" + msg.MessageID;
|
|
|
m += ",流水号:" + msg.SequenceID;
|
|
|
m += ",FunNo:" + msg.FunNo;
|
|
|
m += ",DeviceNo:" + msg.DeviceNo;
|
|
|
ErrorFollow.TraceWrite("重发数据", "", m);
|
|
|
}
|
|
|
bool bk = model.SendData(msg.Bytes, 0, msg.Bytes.Length);
|
|
|
if (bk == false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("发送数据失败", "", "断开连接");
|
|
|
CloseSocket(model);
|
|
|
}
|
|
|
return bk;
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("发送数据失败", "", "断开连接");
|
|
|
CloseSocket(model);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭连接
|
|
|
public void CloseSocket()
|
|
|
{
|
|
|
CloseSocket(this.UseSocket);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭连接
|
|
|
public void CloseSocket(ServerConnection model)
|
|
|
{
|
|
|
if (model.Enabled == false) return;
|
|
|
try
|
|
|
{
|
|
|
model.Disconnect();
|
|
|
}
|
|
|
catch
|
|
|
{ }
|
|
|
}
|
|
|
#endregion
|
|
|
#region 消除已回复消息
|
|
|
public int EndWaitMsg(string SequenceID)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
SocketMessage msg = UseSocket.EndWaitMsg(SequenceID);
|
|
|
if (UseSocket.WaitMsgNumber == this.MaxSendNumber-1) UseSocket.WaitMsgNumber = 0;
|
|
|
if (msg == null) return 0;
|
|
|
return msg.MessageID;
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("ClientSocket.EndWaitMsg", "", ex.Message);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
#endregion
|
|
|
#region 文件下载服务器
|
|
|
public class FileService
|
|
|
{
|
|
|
private int Port = 11111;
|
|
|
public AutoResetEvent AutoReset = new AutoResetEvent(false);
|
|
|
|
|
|
public char SpaceChar = '^';
|
|
|
public static string WebPath = "";
|
|
|
|
|
|
SocketService ser = new SocketService();
|
|
|
|
|
|
public event Action<ServerConnection, Dictionary<string, string>> ReceiveData;
|
|
|
public event Action<ServerConnection> ConnectSocketComplete;
|
|
|
public event Action<ServerConnection> CloseSocketComplete;
|
|
|
|
|
|
public System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
|
|
|
|
|
public FileService()
|
|
|
{
|
|
|
//ser.
|
|
|
ser.IsLongConnect = false;
|
|
|
ser.OutMaxSendNumberCloseConnect = true;
|
|
|
ser.MaxWaitMsgNumber = 16;
|
|
|
ser.MaxSendNumber = 2;
|
|
|
ser.OutTime = 60*3;
|
|
|
ser.RefshSecond = 10;
|
|
|
ser.ReceiveData += ser_ReceiveData;
|
|
|
ser.ConnectSocketComplete += ser_ConnectSocketComplete;
|
|
|
ser.CloseSocketComplete += ser_CloseSocketComplete;
|
|
|
}
|
|
|
|
|
|
#region 连接
|
|
|
void ser_ConnectSocketComplete(ServerConnection model)
|
|
|
{
|
|
|
if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(model);
|
|
|
}
|
|
|
#endregion
|
|
|
#region 关闭连接
|
|
|
void ser_CloseSocketComplete(ServerConnection model)
|
|
|
{
|
|
|
if (model.fs != null)
|
|
|
{
|
|
|
model.fs.Close();
|
|
|
model.fs = null;
|
|
|
}
|
|
|
if (this.CloseSocketComplete != null) this.CloseSocketComplete(model);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 启动监控
|
|
|
public void Start(int Port)
|
|
|
{
|
|
|
this.Port = Port;
|
|
|
if (this.Port == 0) return;
|
|
|
ser.BufferSize = 2 * 1024;
|
|
|
ser.Port = Port;
|
|
|
ser.Start();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 停止监控
|
|
|
public void Stop()
|
|
|
{
|
|
|
if (this.Port == 0) return;
|
|
|
ser.Stop(null);
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 服务器读取到数据时发生
|
|
|
private void ser_ReceiveData(ServerConnection model, DataEventArgs arg2)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
string Data = System.Text.Encoding.GetEncoding("GB2312").GetString(model.Data).Trim('\0');
|
|
|
ErrorFollow.TraceWrite("读取到数据", model.IpAddress, Data);
|
|
|
Dictionary<string, string> ReceiveModel = this.ParseData(Data);
|
|
|
string FunNo = ReceiveModel["TRANS_NO"];
|
|
|
switch (FunNo)
|
|
|
{
|
|
|
case "9999": //文件下载请求
|
|
|
DownFile(model, ReceiveModel);
|
|
|
break;
|
|
|
default:
|
|
|
if (this.ReceiveData != null) this.ReceiveData(model, ReceiveModel);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
#region 解析返回数据
|
|
|
Dictionary<string, string> ParseData(string Data)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(Data) == true) return null;
|
|
|
//if (ErrorFollow.IsDebug == true) ErrorFollow.TraceWrite("解析返回数据", "", Data);
|
|
|
Dictionary<string, string> list = new Dictionary<string, string>();
|
|
|
string[] ss = Data.Split(this.SpaceChar);
|
|
|
foreach (string item in ss)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(item) == true) continue;
|
|
|
string[] sss = item.Split('=');
|
|
|
if (sss.Length == 1)
|
|
|
{
|
|
|
list.Add(sss[0].ToUpper(), "");
|
|
|
}
|
|
|
if (sss.Length == 2)
|
|
|
{
|
|
|
list.Add(sss[0].ToUpper(), sss[1]);
|
|
|
}
|
|
|
}
|
|
|
return list;
|
|
|
}
|
|
|
#endregion
|
|
|
#region 下载文件
|
|
|
public void DownFile(ServerConnection model, Dictionary<string, string> ReceiveModel)
|
|
|
{
|
|
|
|
|
|
NetworkStream ns = null;
|
|
|
Socket socker = null;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
string FilePath = CustomIO.GetKeyValues(ReceiveModel, "FilePath");
|
|
|
if (FilePath.Contains(":") == false) FilePath = FileService.WebPath + FilePath;
|
|
|
bool IsExistsFile = File.Exists(FilePath);
|
|
|
socker = model.GetSocket();
|
|
|
ns = new NetworkStream(socker);
|
|
|
if (IsExistsFile == false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件失败,文件不存在", model.IpAddress, FilePath);
|
|
|
byte[] fileBuffer = new byte[24];
|
|
|
for (int i = 8; i < 24; i++)
|
|
|
{
|
|
|
fileBuffer[i] = 255;
|
|
|
}
|
|
|
ns.Write(fileBuffer, 0, 24);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
//传送头信息:文件长度,MD5校验码
|
|
|
model.fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
|
byte[] HeaderLen = BitConverter.GetBytes(model.fs.Length);
|
|
|
byte[] HeaderHash = oMD5Hasher.ComputeHash(model.fs);
|
|
|
ns.Write(HeaderLen, 0, HeaderLen.Length);
|
|
|
ns.Write(HeaderHash, 0, HeaderHash.Length);
|
|
|
byte[] fileBuffer = new byte[1024 * 4]; // 每次传1KB
|
|
|
int bytesRead;
|
|
|
int totalBytes = 0;
|
|
|
// 将文件流转写入网络流
|
|
|
int index = 0;
|
|
|
model.fs.Position = 0;
|
|
|
do
|
|
|
{
|
|
|
bytesRead = model.fs.Read(fileBuffer, 0, fileBuffer.Length);
|
|
|
if (bytesRead == 0) break;
|
|
|
ns.Write(fileBuffer, 0, bytesRead);
|
|
|
totalBytes += bytesRead; // 发送了的字节数
|
|
|
index++;
|
|
|
if (index == 10)
|
|
|
{
|
|
|
AutoReset.WaitOne(10, false);
|
|
|
index = 0;
|
|
|
model.PrevTime = DateTime.Now;
|
|
|
}
|
|
|
} while (bytesRead > 0);
|
|
|
model.fs.Close();
|
|
|
model.fs = null;
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
if (model.fs != null)
|
|
|
{
|
|
|
model.fs.Close();
|
|
|
model.fs = null;
|
|
|
}
|
|
|
ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
}
|
|
|
#endregion
|
|
|
#region 文件下载客户端
|
|
|
public class FileClient
|
|
|
{
|
|
|
public static string IpAddress = "";
|
|
|
public static int Port = 11111;
|
|
|
public static string SpaceChar = "^";
|
|
|
|
|
|
public int CilentID = 0;
|
|
|
public int DownFileID = 0;
|
|
|
public List<NetDownFile> FileManage = null;
|
|
|
public int ModelType = 0;
|
|
|
public bool IsSaveList = true;
|
|
|
public bool IsErrorStopDown = false;
|
|
|
public float Version = 0;
|
|
|
public object CustomModel = null;
|
|
|
private AutoResetEvent AutoReset = new AutoResetEvent(false);
|
|
|
public bool IsRun = true;
|
|
|
public string tempFilePath = "";
|
|
|
public string RunTime = "";
|
|
|
|
|
|
public event Action<FileClient> DownFileComplete; //下载文件完成
|
|
|
public event Action<FileClient> DownFileErrorComplete; //下载文件错误时发生
|
|
|
public event Action<NetDownFile> DownNoFileComplete; //服务器不存在这个文件
|
|
|
|
|
|
#region 启动监控
|
|
|
public void Start()
|
|
|
{
|
|
|
IsRun = true;
|
|
|
Thread t = new Thread(this.OnStart);
|
|
|
t.Start();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 启动监控
|
|
|
public void Start(int ModelType, List<NetDownFile> ListModel)
|
|
|
{
|
|
|
this.ModelType = ModelType;
|
|
|
this.FileManage = ListModel;
|
|
|
IsRun = true;
|
|
|
string dir = SystemInfo.AppPath() + "TempFileDown";
|
|
|
if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir);
|
|
|
tempFilePath = dir + "/" + DateTime.Now.ToString("MMddHHmmssfff") + ".txt";
|
|
|
Thread t = new Thread(this.OnStart);
|
|
|
t.Start();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 启动监控
|
|
|
public void Start(int ModelType, string filePath, List<NetDownFile> ListModel)
|
|
|
{
|
|
|
this.ModelType = ModelType;
|
|
|
this.FileManage = ListModel;
|
|
|
IsRun = true;
|
|
|
string dir = SystemInfo.AppPath() + "TempFileDown";
|
|
|
if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir);
|
|
|
tempFilePath = filePath;
|
|
|
Thread t = new Thread(this.OnStart);
|
|
|
t.Start();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 停止监控
|
|
|
public void Stop()
|
|
|
{
|
|
|
FileManage.Clear();
|
|
|
IsRun = false;
|
|
|
AutoReset.Set();
|
|
|
}
|
|
|
#endregion
|
|
|
#region 保存下载文件列表
|
|
|
public void SaveFileList()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (this.IsSaveList == false) return;
|
|
|
if (string.IsNullOrEmpty(tempFilePath) == true)
|
|
|
{
|
|
|
string dir = SystemInfo.AppPath() + "TempFileDown";
|
|
|
if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir);
|
|
|
tempFilePath = dir + "/" + DateTime.Now.ToString("MMddHHmmssfff") + ".txt";
|
|
|
}
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
sb.Append("DownFileID=" + this.DownFileID + FileClient.SpaceChar);
|
|
|
sb.Append("ModelType=" + this.ModelType + FileClient.SpaceChar);
|
|
|
sb.Append("RowCount=" + FileManage.Count + FileClient.SpaceChar);
|
|
|
sb.Append("IsErrorStopDown=" + IsErrorStopDown.ToString() + FileClient.SpaceChar);
|
|
|
int index = 1;
|
|
|
foreach (NetDownFile item in FileManage)
|
|
|
{
|
|
|
sb.Append("DownFileName[" + index + "]=" + item.DownFileName + FileClient.SpaceChar);
|
|
|
sb.Append("DownID[" + index + "]=" + item.DownID + FileClient.SpaceChar);
|
|
|
sb.Append("SaveFileName[" + index + "]=" + item.SaveFileName + FileClient.SpaceChar);
|
|
|
sb.Append("IsDownComplete[" + index + "]=" + item.IsDownComplete.ToString() + FileClient.SpaceChar);
|
|
|
sb.Append("FileType[" + index + "]=" + item.FileType + FileClient.SpaceChar);
|
|
|
index++;
|
|
|
}
|
|
|
using (StreamWriter sw = new StreamWriter(tempFilePath, false, System.Text.Encoding.GetEncoding("GB2312")))
|
|
|
{
|
|
|
sw.WriteLine(sb.ToString());
|
|
|
sw.Close();
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("保存下载文件列表", ex.StackTrace, ex.Message);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 文件下载
|
|
|
void OnStart()
|
|
|
{
|
|
|
DateTime StartTime = DateTime.Now;
|
|
|
SaveFileList();
|
|
|
FileStream fs = null;
|
|
|
NetworkStream ns = null;
|
|
|
TcpClient tcp = null;
|
|
|
try
|
|
|
{
|
|
|
System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher = new System.Security.Cryptography.MD5CryptoServiceProvider();
|
|
|
bool bk = false;
|
|
|
#region 循环
|
|
|
foreach (NetDownFile item in FileManage)
|
|
|
{
|
|
|
if (item.IsDownComplete == true) continue;
|
|
|
try
|
|
|
{
|
|
|
if (File.Exists(item.SaveFileName) == true) File.Delete(item.SaveFileName);
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件", "", item.SaveFileName + "文件删除失败");
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
string dir = Path.GetDirectoryName(item.SaveFileName);
|
|
|
if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir);
|
|
|
string path = item.SaveFileName + ".temp";
|
|
|
if (File.Exists(path) == true)
|
|
|
{
|
|
|
DateTime dt = DateTime.Now;
|
|
|
FileInfo finfo = new FileInfo(path);
|
|
|
if (dt.AddMinutes(-1) < finfo.LastWriteTime)
|
|
|
{
|
|
|
finfo = null;
|
|
|
ErrorFollow.TraceWrite("下载文件", "", path + "文件已经在下载");
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
File.Delete(path);
|
|
|
}
|
|
|
IPAddress broadcast = IPAddress.Parse(IpAddress);
|
|
|
IPEndPoint ep = new IPEndPoint(broadcast, Port);
|
|
|
tcp = new TcpClient();
|
|
|
tcp.Connect(ep);
|
|
|
ns = tcp.GetStream();
|
|
|
//这里发送文件下载请求
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
if (item.FileType == 0)
|
|
|
{
|
|
|
sb.Append("TRANS_NO=9998" + FileClient.SpaceChar);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sb.Append("TRANS_NO=9999" + FileClient.SpaceChar);
|
|
|
}
|
|
|
sb.Append("FilePath=" + item.DownFileName + FileClient.SpaceChar);
|
|
|
byte[] bytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(sb.ToString());
|
|
|
ns.Write(bytes, 0, bytes.Length);
|
|
|
//AutoReset.WaitOne(1000, false);
|
|
|
byte[] fileHeader = new byte[24];
|
|
|
byte[] fileBuffer = new byte[1024 * 4]; // 每次收1KB
|
|
|
if (File.Exists(path)) File.Delete(path);
|
|
|
fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
|
|
|
|
|
|
// 从缓存buffer中读入到文件流中
|
|
|
int bytesRead;
|
|
|
int totalBytes = 0;
|
|
|
int index = 0;
|
|
|
byte[] HeaderHash = null;
|
|
|
string CheckOutCode = "";
|
|
|
do
|
|
|
{
|
|
|
bytesRead = ns.Read(fileBuffer, 0, fileBuffer.Length);
|
|
|
if (totalBytes < 24)
|
|
|
{
|
|
|
int count = 24 - totalBytes;
|
|
|
if (bytesRead < count) count = bytesRead;
|
|
|
Buffer.BlockCopy(fileBuffer, 0, fileHeader, totalBytes, count);
|
|
|
if (totalBytes + count >= 24)
|
|
|
{
|
|
|
item.Length = BitConverter.ToInt64(fileHeader, 0);
|
|
|
if (item.Length == 0) break;
|
|
|
item.CheckOutCode = BitConverter.ToString(fileHeader, 8, 16);
|
|
|
if (bytesRead > 24) fs.Write(fileBuffer, count, bytesRead - count);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
fs.Write(fileBuffer, 0, bytesRead);
|
|
|
}
|
|
|
totalBytes += bytesRead;
|
|
|
if (item.Length > 0 && totalBytes >= item.Length + 24) break;
|
|
|
if (index == 10) { AutoReset.WaitOne(10, false); if (IsRun == false) return; index = 0; }
|
|
|
} while (bytesRead > 0);
|
|
|
if (fs.Length > 0)
|
|
|
{
|
|
|
fs.Position = 0;
|
|
|
HeaderHash = oMD5Hasher.ComputeHash(fs);
|
|
|
CheckOutCode = BitConverter.ToString(HeaderHash, 0, 16);
|
|
|
}
|
|
|
long FileLength = fs.Length;
|
|
|
fs.Close();
|
|
|
fs = null;
|
|
|
ns.Close();
|
|
|
ns = null;
|
|
|
tcp.Close();
|
|
|
tcp = null;
|
|
|
bool bkk = true;
|
|
|
if (item.Length == 0 && fileHeader.Length == 24)
|
|
|
{
|
|
|
bkk = false;
|
|
|
for (int i = 8; i < 24; i++)
|
|
|
{
|
|
|
if (fileHeader[i] != 255) { bkk = true; break; }
|
|
|
}
|
|
|
}
|
|
|
if (bkk==false)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件", "", "服务器不存在这个文件:" + item.DownFileName);
|
|
|
item.IsDownComplete = true;
|
|
|
if (this.DownNoFileComplete != null) this.DownNoFileComplete(item);
|
|
|
File.Delete(path);
|
|
|
bk = false;
|
|
|
break;
|
|
|
}
|
|
|
else if (item.Length == 0 || HeaderHash == null)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错", "文件长度不能等于0", item.DownFileName);
|
|
|
File.Delete(path);
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
else if (FileLength != item.Length)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错", "文件长度错误", item.DownFileName);
|
|
|
File.Delete(path);
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
else if (CheckOutCode != item.CheckOutCode)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错", "MD5校验失败", item.DownFileName);
|
|
|
File.Delete(path);
|
|
|
bk = true;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件成功", "", item.DownFileName);
|
|
|
item.IsDownComplete = true;
|
|
|
File.Move(path, item.SaveFileName);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
if (bk == false)
|
|
|
{
|
|
|
DateTime StopTime = DateTime.Now;
|
|
|
TimeSpan ts = StopTime - StartTime;
|
|
|
RunTime = ts.ToString();
|
|
|
IsRun = false;
|
|
|
if (this.IsSaveList == true) File.Delete(tempFilePath);
|
|
|
if (this.DownFileComplete != null) this.DownFileComplete(this);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (this.IsErrorStopDown == true)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件错误", "", "停止下载");
|
|
|
if (this.DownFileErrorComplete != null) this.DownFileErrorComplete(this);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错", "", "60秒后重新下载");
|
|
|
AutoReset.WaitOne(60000, false);
|
|
|
if (IsRun == false) return;
|
|
|
OnStart();
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (fs != null)
|
|
|
{
|
|
|
fs.Close();
|
|
|
fs = null;
|
|
|
}
|
|
|
if (ns != null)
|
|
|
{
|
|
|
ns.Close();
|
|
|
ns = null;
|
|
|
}
|
|
|
if (tcp != null)
|
|
|
{
|
|
|
tcp.Close();
|
|
|
tcp = null;
|
|
|
}
|
|
|
}
|
|
|
catch
|
|
|
{ }
|
|
|
|
|
|
if (this.IsErrorStopDown == true)
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错", ex.StackTrace, ex.Message);
|
|
|
if (this.DownFileErrorComplete != null) this.DownFileErrorComplete(this);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ErrorFollow.TraceWrite("下载文件出错,60秒后重新下载", ex.StackTrace, ex.Message);
|
|
|
AutoReset.WaitOne(60000, false);
|
|
|
if (IsRun == false) return;
|
|
|
OnStart();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 文件下载信息
|
|
|
public class NetDownFile
|
|
|
{
|
|
|
public int DownID = 0;
|
|
|
public string SaveFileName = "";
|
|
|
public string DownFileName = "";
|
|
|
public long Length = 0;
|
|
|
public string CheckOutCode = "";
|
|
|
public bool IsDownComplete = false;
|
|
|
public int FileType = 1; //0医生照片下载1文件下载
|
|
|
|
|
|
|
|
|
public void CreateFile()
|
|
|
{
|
|
|
if (File.Exists(SaveFileName) == true) File.Delete(SaveFileName);
|
|
|
}
|
|
|
|
|
|
public NetDownFile Copy()
|
|
|
{
|
|
|
NetDownFile model = new NetDownFile();
|
|
|
model.DownID = this.DownID;
|
|
|
model.SaveFileName = this.SaveFileName;
|
|
|
model.DownFileName = this.DownFileName;
|
|
|
model.Length = this.Length;
|
|
|
model.CheckOutCode = this.CheckOutCode;
|
|
|
model.IsDownComplete = this.IsDownComplete;
|
|
|
model.FileType = this.FileType;
|
|
|
return model;
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
}
|