960 lines
34 KiB
C#
960 lines
34 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Drawing;
|
||
using System.Net;
|
||
using System.Text;
|
||
using System.Windows.Forms;
|
||
|
||
namespace NetWorkHelper
|
||
{
|
||
public partial class AxUdpClient : Component
|
||
{
|
||
#region 构造函数
|
||
public AxUdpClient()
|
||
{
|
||
InitializeComponent();
|
||
}
|
||
|
||
public AxUdpClient(IContainer container)
|
||
{
|
||
container.Add(this);
|
||
|
||
InitializeComponent();
|
||
}
|
||
#endregion
|
||
|
||
#region 变量
|
||
private UdpLibrary _udpLibrary;
|
||
|
||
/// <summary>
|
||
/// 文件发送列表管理器
|
||
/// </summary>
|
||
private Dictionary<string, SendFileManager> _sendFileManagerList;
|
||
|
||
/// <summary>
|
||
/// 文件接收列表管理器
|
||
/// </summary>
|
||
private Dictionary<string, ReceiveFileManager> _receiveFileManagerList;
|
||
private object _sendsyncLock = new object();
|
||
private object _receivesyncLock = new object();
|
||
#endregion
|
||
|
||
#region 属性
|
||
|
||
/// <summary>
|
||
/// 传输协议是否启用AxUDPClient内部封装协议
|
||
/// </summary>
|
||
[Description("传输协议是否启用AxUDPClient内部封装协议")]
|
||
[Category("UDP客户端属性")]
|
||
public bool IsAxAgreement { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// UDP客户端基类
|
||
/// </summary>
|
||
[Description("UDP客户端基类")]
|
||
[Category("UDP客户端属性")]
|
||
public UdpLibrary UdpLibrary
|
||
{
|
||
get
|
||
{
|
||
if (_udpLibrary == null)
|
||
{
|
||
_udpLibrary = new UdpLibrary(LocalPort);
|
||
_udpLibrary.ReceiveData += new ReceiveDataEventHandler(UdpLibraryReceiveData);
|
||
}
|
||
return _udpLibrary;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 文件发送列表管理器
|
||
/// </summary>
|
||
[Description("文件发送列表管理器")]
|
||
[Category("UDP客户端属性")]
|
||
public Dictionary<string, SendFileManager> SendFileManagerList
|
||
{
|
||
get
|
||
{
|
||
if (_sendFileManagerList == null)
|
||
{
|
||
_sendFileManagerList = new Dictionary<string, SendFileManager>(10);
|
||
}
|
||
return _sendFileManagerList;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 文件接收列表管理器
|
||
/// </summary>
|
||
[Description("文件接收列表管理器")]
|
||
[Category("UDP客户端属性")]
|
||
public Dictionary<string, ReceiveFileManager> ReceiveFileManagerList
|
||
{
|
||
get
|
||
{
|
||
if (_receiveFileManagerList == null)
|
||
{
|
||
_receiveFileManagerList = new Dictionary<string, ReceiveFileManager>(10);
|
||
}
|
||
return _receiveFileManagerList;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 远程监听IP
|
||
/// </summary>
|
||
[Description("远程监听IP")]
|
||
[Category("UDP客户端属性")]
|
||
public string RemoteIp { get; set; } = "127.0.0.1";
|
||
|
||
/// <summary>
|
||
/// 远程监听端口
|
||
/// </summary>
|
||
[Description("远程监听端口")]
|
||
[Category("UDP客户端属性")]
|
||
public int RemotePort { get; set; } = 8900;
|
||
|
||
/// <summary>
|
||
/// 本地监听IP
|
||
/// </summary>
|
||
[Description("本地监听IP")]
|
||
[Category("UDP客户端属性")]
|
||
public int LocalPort { get; set; } = 8899;
|
||
|
||
/// <summary>
|
||
/// 远程主机网络端点
|
||
/// </summary>
|
||
[Description("远程主机网络端点")]
|
||
[Category("UDP客户端属性")]
|
||
public IPEndPoint RemoteEp
|
||
{
|
||
get { return new IPEndPoint(IPAddress.Parse(RemoteIp), RemotePort); }
|
||
}
|
||
|
||
public FileTansfersContainer FileTansfersControl
|
||
{
|
||
get
|
||
{
|
||
if (fileTansfersContainer == null)
|
||
{
|
||
fileTansfersContainer = new FileTansfersContainer();
|
||
}
|
||
return fileTansfersContainer;
|
||
}
|
||
set
|
||
{
|
||
if (value == null)
|
||
fileTansfersContainer = new FileTansfersContainer();
|
||
else
|
||
{
|
||
fileTansfersContainer = value;
|
||
}
|
||
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 方法
|
||
/// <summary>
|
||
/// 启动监听
|
||
/// </summary>
|
||
public void Start()
|
||
{
|
||
UdpLibrary.Start();
|
||
}
|
||
/// <summary>
|
||
/// 关闭监听
|
||
/// </summary>
|
||
public void Stop()
|
||
{
|
||
UdpLibrary.Stop();
|
||
}
|
||
/// <summary>
|
||
/// 继承Udp基类接收数据方法
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void UdpLibraryReceiveData(object sender, ReceiveDataEventArgs e)
|
||
{
|
||
//若不适用内部封装协议则只激活接受原始数据事件
|
||
if (!IsAxAgreement)
|
||
{
|
||
OnReceiveByte(e);
|
||
return;
|
||
}
|
||
MsgCell cell = new MsgCell();
|
||
cell.FromBuffer(e.Buffer);
|
||
switch (cell.MessageId)
|
||
{
|
||
case (int)Command.RequestSendTextMSg:
|
||
OnReceiveTextMsg((MsgTypeCell)cell.Data);
|
||
break;
|
||
case (int)Command.ResponeSendFile:
|
||
OnResponeSendFile((ResponeTraFransfersFile)cell.Data);
|
||
break;
|
||
case (int)Command.ResponeSendFilePack:
|
||
OnResponeSendFilePack((ResponeTraFransfersFile)cell.Data);
|
||
break;
|
||
case (int)Command.RequestCancelReceiveFile:
|
||
OnRequestCancelReceiveFile(cell.Data.ToString());
|
||
break;
|
||
case (int)Command.RequestSendFile:
|
||
OnStartRecieve((TraFransfersFileStart)cell.Data, e.RemoteIP);
|
||
break;
|
||
case (int)Command.RequestSendFilePack:
|
||
OnRecieveBuffer((TraFransfersFile)cell.Data, e.RemoteIP);
|
||
break;
|
||
case (int)Command.RequestCancelSendFile:
|
||
OnRequestCancelSendFile(cell.Data.ToString(), e.RemoteIP);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回是否允许发送,在发送列表中的文件不能重复发送(避免文件被占用导致错误)
|
||
/// </summary>
|
||
/// <param name="sendFileManager"></param>
|
||
/// <returns></returns>
|
||
public bool CanSend(SendFileManager sendFileManager)
|
||
{
|
||
return !SendFileManagerList.ContainsKey(sendFileManager.MD5);
|
||
}
|
||
/// <summary>
|
||
/// 发送文件
|
||
/// </summary>
|
||
/// <param name="fileName">文件路径(包含完整的文件名)</param>
|
||
public void SendFile(string fileName)
|
||
{
|
||
SendFileManager sendFileManager = new SendFileManager(fileName);
|
||
Image img = Icon.ExtractAssociatedIcon(fileName).ToBitmap();
|
||
SendFile(sendFileManager, img);
|
||
}
|
||
/// <summary>
|
||
/// 发送文件
|
||
/// </summary>
|
||
/// <param name="sendFileManager">需要发送的文件类</param>
|
||
/// <param name="image">文件ICO图标</param>
|
||
public void SendFile(SendFileManager sendFileManager, Image image)
|
||
{
|
||
if (SendFileManagerList.ContainsKey(sendFileManager.MD5))
|
||
{
|
||
throw new Exception(string.Format("文件 {0} 正在发送,不能发送重复的文件。", sendFileManager.FileName));
|
||
}
|
||
else
|
||
{
|
||
SendFileManagerList.Add(sendFileManager.MD5, sendFileManager);
|
||
sendFileManager.ReadFileBuffer += new ReadFileBufferEventHandler(SendFileManageReadFileBuffer);
|
||
TraFransfersFileStart ts = new TraFransfersFileStart(sendFileManager.MD5, sendFileManager.Name, image, sendFileManager.Length, sendFileManager.PartCount, sendFileManager.PartSize);
|
||
//添加
|
||
AddSendItems(sendFileManager, image);
|
||
Send((int)Command.RequestSendFile, ts);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消发送
|
||
/// </summary>
|
||
/// <param name="md5">MD5校验文件</param>
|
||
public void CancelSend(string md5)
|
||
{
|
||
SendFileManager sendFileManager;
|
||
if (SendFileManagerList.TryGetValue(md5, out sendFileManager))
|
||
{
|
||
Send((int)Command.RequestCancelSendFile, md5);
|
||
lock (_sendsyncLock)
|
||
{
|
||
SendFileManagerList.Remove(md5);
|
||
sendFileManager.Dispose();
|
||
sendFileManager = null;
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 读取文件并发送文件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void SendFileManageReadFileBuffer(
|
||
object sender, ReadFileBufferEventArgs e)
|
||
{
|
||
SendFileManager sendFileManager = sender as SendFileManager;
|
||
TraFransfersFile ts = new TraFransfersFile(sendFileManager.MD5, e.Index, e.Buffer);
|
||
Send((int)Command.RequestSendFilePack, ts);
|
||
}
|
||
/// <summary>
|
||
/// 发送信息
|
||
/// </summary>
|
||
/// <param name="messageId">消息标识</param>
|
||
/// <param name="data">序列化数据</param>
|
||
public void Send(int messageId, object data)
|
||
{
|
||
Send(messageId, data, RemoteEp);
|
||
}
|
||
|
||
public void SendText(string strmsg)
|
||
{
|
||
byte[] dataBytes = Encoding.Default.GetBytes(strmsg);
|
||
MsgTypeCell msgTypeCell = new MsgTypeCell(MsgType.TxtMsg, dataBytes);
|
||
MsgCell cell = new MsgCell(0x000010, msgTypeCell);
|
||
UdpLibrary.Send(cell, RemoteEp);
|
||
}
|
||
|
||
public void SendImage(Image img)
|
||
{
|
||
MsgTypeCell msgTypeCell = new MsgTypeCell(MsgType.Pic, ImageHelper.ImageToBytes(img));
|
||
MsgCell cell = new MsgCell(0x000010, msgTypeCell);
|
||
UdpLibrary.Send(cell, RemoteEp);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送信息
|
||
/// </summary>
|
||
/// <param name="messageId">消息标识</param>
|
||
/// <param name="data">序列化数据</param>
|
||
/// <param name="remoteIp">远程主机IP</param>
|
||
public void Send(int messageId, object data, IPEndPoint remoteIp)
|
||
{
|
||
MsgCell cell = new MsgCell(messageId, data);
|
||
UdpLibrary.Send(cell, remoteIp);
|
||
}
|
||
/// <summary>
|
||
/// 发送信息
|
||
/// </summary>
|
||
/// <param name="data">数据</param>
|
||
/// <param name="remoteIp">远程主机IP</param>
|
||
public void Send(byte[] data)
|
||
{
|
||
UdpLibrary.Send(data, RemoteEp);
|
||
}
|
||
/// <summary>
|
||
/// 响应发送文件方法
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
private void OnResponeSendFile(ResponeTraFransfersFile data)
|
||
{
|
||
SendFileManager sendFileManager;
|
||
if (!SendFileManagerList.TryGetValue(data.MD5, out sendFileManager))
|
||
{
|
||
return;
|
||
}
|
||
if (data.Size > 0)
|
||
{
|
||
OnFileSendBuffer(new FileSendBufferEventArgs(sendFileManager, data.Size));
|
||
}
|
||
if (data.Index == 0)
|
||
{
|
||
if (sendFileManager != null)
|
||
{
|
||
OnFileSendAccept(new FileSendEventArgs(sendFileManager));
|
||
sendFileManager.Read(data.Index);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (data.Index == -1)
|
||
{
|
||
OnFileSendRefuse(new FileSendEventArgs(sendFileManager));
|
||
}
|
||
SendFileManagerList.Remove(data.MD5);
|
||
sendFileManager.Dispose();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 响应发送文件包方法
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
private void OnResponeSendFilePack(ResponeTraFransfersFile data)
|
||
{
|
||
SendFileManager sendFileManager;
|
||
if (!SendFileManagerList.TryGetValue(data.MD5, out sendFileManager))
|
||
{
|
||
return;
|
||
}
|
||
if (data.Size > 0)
|
||
{
|
||
OnFileSendBuffer(new FileSendBufferEventArgs(sendFileManager, data.Size));
|
||
}
|
||
if (data.Index >= 0)
|
||
{
|
||
if (sendFileManager != null)
|
||
{
|
||
sendFileManager.Read(data.Index);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (data.Index == -1)
|
||
{
|
||
OnFileSendRefuse(new FileSendEventArgs(sendFileManager));
|
||
}
|
||
else if (data.Index == -2)
|
||
{
|
||
OnFileSendComplete(new FileSendEventArgs(sendFileManager));
|
||
}
|
||
SendFileManagerList.Remove(data.MD5);
|
||
sendFileManager.Dispose();
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 请求取消接收文件方法
|
||
/// </summary>
|
||
/// <param name="md5"></param>
|
||
private void OnRequestCancelReceiveFile(string md5)
|
||
{
|
||
SendFileManager sendFileManager;
|
||
if (SendFileManagerList.TryGetValue(md5, out sendFileManager))
|
||
{
|
||
OnFileSendCancel(new FileSendEventArgs(sendFileManager));
|
||
lock (_sendsyncLock)
|
||
{
|
||
SendFileManagerList.Remove(md5);
|
||
sendFileManager.Dispose();
|
||
sendFileManager = null;
|
||
}
|
||
}
|
||
|
||
Send((int)Command.ResponeCancelReceiveFile, "OK");
|
||
}
|
||
|
||
#region 接收方法
|
||
/// <summary>
|
||
/// 允许接收
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
public void AcceptReceive(RequestSendFileEventArgs e)
|
||
{
|
||
TraFransfersFileStart traFransfersFileStart = e.TraFransfersFileStart;
|
||
IPEndPoint remoteIP = e.RemoteIP;
|
||
ResponeTraFransfersFile responeTraFransfersFile;
|
||
if (e.Cancel)
|
||
{
|
||
responeTraFransfersFile = new ResponeTraFransfersFile(traFransfersFileStart.MD5, 0, -1);
|
||
Send((int)Command.ResponeSendFile, responeTraFransfersFile, remoteIP);
|
||
}
|
||
else
|
||
{
|
||
ReceiveFileManager receiveFileManager;
|
||
if (!ReceiveFileManagerList.TryGetValue(traFransfersFileStart.MD5, out receiveFileManager))
|
||
{
|
||
receiveFileManager = new ReceiveFileManager(traFransfersFileStart.MD5, e.Path, traFransfersFileStart.FileName, traFransfersFileStart.PartCount, traFransfersFileStart.PartSize, traFransfersFileStart.Length, remoteIP);
|
||
receiveFileManager.ReceiveFileComplete += new FileReceiveCompleteEventHandler(ReceiveFileManagerReceiveFileComplete);
|
||
receiveFileManager.ReceiveFileTimeout += new EventHandler(ReceiveFileManagerReceiveFileTimeout);
|
||
ReceiveFileManagerList.Add(traFransfersFileStart.MD5, receiveFileManager);
|
||
receiveFileManager.Start();
|
||
}
|
||
responeTraFransfersFile = new ResponeTraFransfersFile(traFransfersFileStart.MD5, 0, 0);
|
||
Send((int)Command.ResponeSendFile, responeTraFransfersFile, remoteIP);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 取消接收
|
||
/// </summary>
|
||
/// <param name="md5"></param>
|
||
/// <param name="remoteIP"></param>
|
||
public void CancelReceive(string md5, IPEndPoint remoteIP)
|
||
{
|
||
ReceiveFileManager receiveFileManager;
|
||
if (ReceiveFileManagerList.TryGetValue(md5, out receiveFileManager))
|
||
{
|
||
Send((int)Command.RequestCancelReceiveFile, md5, remoteIP);
|
||
lock (_receivesyncLock)
|
||
{
|
||
ReceiveFileManagerList.Remove(md5);
|
||
receiveFileManager.Dispose();
|
||
receiveFileManager = null;
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 完成接收文件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void ReceiveFileManagerReceiveFileComplete(
|
||
object sender, FileReceiveCompleteEventArgs e)
|
||
{
|
||
ReceiveFileManager receiveFileManager =
|
||
sender as ReceiveFileManager;
|
||
OnFileReceiveComplete(new FileReceiveEventArgs(receiveFileManager));
|
||
ReceiveFileManagerList.Remove(receiveFileManager.MD5);
|
||
}
|
||
|
||
private void ReceiveFileManagerReceiveFileTimeout(
|
||
object sender, EventArgs e)
|
||
{
|
||
ReceiveFileManager receiveFileManager =
|
||
sender as ReceiveFileManager;
|
||
ResponeTraFransfersFile responeTraFransfersFile =
|
||
new ResponeTraFransfersFile(
|
||
receiveFileManager.MD5,
|
||
0,
|
||
receiveFileManager.GetNextReceiveIndex());
|
||
Send(
|
||
(int)Command.ResponeSendFilePack,
|
||
responeTraFransfersFile,
|
||
receiveFileManager.RemoteIP);
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 事件
|
||
|
||
#region 发送文件事件
|
||
|
||
#region 文件发送被取消事件(当发送文件正在被接收中时对方取消接收)
|
||
[Description("文件发送被取消事件\r\n(当发送文件正在被接收中时对方取消接收)")]
|
||
public event FileSendEventHandler FileSendCancel;
|
||
/// <summary>
|
||
/// 文件发送时被取消时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileSendCancel(FileSendEventArgs e)
|
||
{
|
||
FileTransfersItem item = e.SendFileManager.Tag as FileTransfersItem;
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
fileTansfersContainer.RemoveItem(item);
|
||
item.Dispose();
|
||
}));
|
||
}
|
||
|
||
FileSendCancel?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 发送文件被允许接收时触发事件
|
||
[Description("发送文件被允许接收时触发事件")]
|
||
public event FileSendEventHandler FileSendAccept;
|
||
/// <summary>
|
||
/// 文件被接收时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileSendAccept(FileSendEventArgs e)
|
||
{
|
||
FileTransfersItem item = e.SendFileManager.Tag as FileTransfersItem;
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
item.Start();
|
||
}));
|
||
}
|
||
|
||
FileSendAccept?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 文件正在发送时触发事件
|
||
[Description("文件正在发送时触发事件")]
|
||
public event FileSendBufferEventHandler FileSendBuffer;
|
||
/// <summary>
|
||
/// 文件正在发送时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileSendBuffer(FileSendBufferEventArgs e)
|
||
{
|
||
FileTransfersItem item = e.SendFileManager.Tag as FileTransfersItem;
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
item.TotalTransfersSize += e.Size;
|
||
}));
|
||
}
|
||
FileSendBuffer?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 发送文件被拒绝接收时触发事件
|
||
[Description("发送文件被拒绝接收时触发事件")]
|
||
public event FileSendEventHandler FileSendRefuse;
|
||
/// <summary>
|
||
/// 发送文件被拒绝接收时触发事件
|
||
/// </summary>Refuse to receive file
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileSendRefuse(FileSendEventArgs e)
|
||
{
|
||
FileTransfersItem item = e.SendFileManager.Tag as FileTransfersItem;
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
fileTansfersContainer.RemoveItem(item);
|
||
item.Dispose();
|
||
}));
|
||
}
|
||
|
||
FileSendRefuse?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 文件发送完成时触发事件
|
||
[Description("文件发送完成时触发事件")]
|
||
public event FileSendEventHandler FileSendComplete;
|
||
/// <summary>
|
||
/// 文件发送完成时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileSendComplete(FileSendEventArgs e)
|
||
{
|
||
FileTransfersItem item = e.SendFileManager.Tag as FileTransfersItem;
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
fileTansfersContainer.RemoveItem(item);
|
||
item.Dispose();
|
||
}));
|
||
}
|
||
|
||
FileSendComplete?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 取消发送文件事件方法
|
||
/// <summary>
|
||
/// 取消发送文件事件方法
|
||
/// </summary>
|
||
/// <param name="md5"></param>
|
||
/// <param name="remoteIP"></param>
|
||
private void OnRequestCancelSendFile(string md5, IPEndPoint remoteIP)
|
||
{
|
||
ReceiveFileManager receiveFileManager;
|
||
if (ReceiveFileManagerList.TryGetValue(md5, out receiveFileManager))
|
||
{
|
||
OnFileReceiveCancel(new FileReceiveEventArgs(receiveFileManager));
|
||
lock (_receivesyncLock)
|
||
{
|
||
ReceiveFileManagerList.Remove(md5);
|
||
receiveFileManager.Dispose();
|
||
receiveFileManager = null;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
FileReceiveEventArgs fe = new FileReceiveEventArgs();
|
||
fe.Tag = md5;
|
||
OnFileReceiveCancel(fe);
|
||
}
|
||
Send(
|
||
(int)Command.ResponeCancelSendFile, "OK", remoteIP);
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region 接收文件事件
|
||
|
||
|
||
|
||
#region 接收文本数据事件
|
||
public delegate void ReceiveTextMsgEventHandler(MsgTypeCell msgTypeCell);
|
||
[Description("接收文本数据事件")]
|
||
public event ReceiveTextMsgEventHandler ReceiveTextMsg;
|
||
/// <summary>
|
||
/// 文件被接收时触发事件
|
||
/// </summary>
|
||
/// <param name="bytes"></param>
|
||
protected virtual void OnReceiveTextMsg(MsgTypeCell msgTypeCell)
|
||
{
|
||
ReceiveTextMsg?.Invoke(msgTypeCell);
|
||
}
|
||
#endregion
|
||
|
||
#region 请求接收文件响应时触发事件
|
||
[Description("请求接收文件响应时触发事件")]
|
||
public event RequestSendFileEventHandler FileRecieveRequest;
|
||
/// <summary>
|
||
/// 请求接收文件响应时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileRecieveRequest(RequestSendFileEventArgs e)
|
||
{
|
||
AddReadyReceiveItem(e);
|
||
FileRecieveRequest?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 文件被读取时(正在读取)触发事件
|
||
[Description("文件被读取时(正在读取)触发事件")]
|
||
public event FileReceiveBufferEventHandler FileReceiveBuffer;
|
||
/// <summary>
|
||
/// 文件被读取时(正在读取)触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileReceiveBuffer(FileReceiveBufferEventArgs e)
|
||
{
|
||
FileTransfersItem item = fileTansfersContainer.Search(e.ReceiveFileManager.MD5);
|
||
if (item != null)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
item.TotalTransfersSize += e.Size;
|
||
}));
|
||
}
|
||
|
||
FileReceiveBuffer?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 文件接收完成时触发事件
|
||
[Description("文件接收完成时触发事件")]
|
||
public event FileReceiveEventHandler FileReceiveComplete;
|
||
/// <summary>
|
||
/// 文件接收完成时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileReceiveComplete(FileReceiveEventArgs e)
|
||
{
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
fileTansfersContainer.RemoveItem(e.ReceiveFileManager.MD5);
|
||
}));
|
||
FileReceiveComplete?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 文件接收时被取消发送触发事件
|
||
[Description("接收文件被取消时触发事件\r\n(当正在接收对方文件时对方取消发送)")]
|
||
public event FileReceiveEventHandler FileReceiveCancel;
|
||
/// <summary>
|
||
/// 文件接收时被取消发送触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnFileReceiveCancel(FileReceiveEventArgs e)
|
||
{
|
||
string md5 = string.Empty;
|
||
if (e.ReceiveFileManager != null)
|
||
{
|
||
md5 = e.ReceiveFileManager.MD5;
|
||
}
|
||
else
|
||
{
|
||
md5 = e.Tag.ToString();
|
||
}
|
||
|
||
FileTransfersItem item = fileTansfersContainer.Search(md5);
|
||
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
fileTansfersContainer.RemoveItem(item);
|
||
}));
|
||
FileReceiveCancel?.Invoke(this, e);
|
||
}
|
||
#endregion
|
||
|
||
#region 接收文件事件方法
|
||
/// <summary>
|
||
/// 接收文件事件方法
|
||
/// </summary>
|
||
/// <param name="traFransfersFile"></param>
|
||
/// <param name="remoteEp"></param>
|
||
private void OnRecieveBuffer(TraFransfersFile traFransfersFile, IPEndPoint remoteEp)
|
||
{
|
||
ReceiveFileManager receiveFileManager;
|
||
|
||
if (!ReceiveFileManagerList.TryGetValue(traFransfersFile.MD5, out receiveFileManager))
|
||
{
|
||
return;
|
||
}
|
||
if (receiveFileManager != null)
|
||
{
|
||
ResponeTraFransfersFile responeTraFransfersFile;
|
||
int size = receiveFileManager.ReceiveBuffer(traFransfersFile.Index, traFransfersFile.Buffer);
|
||
|
||
if (receiveFileManager.Completed)
|
||
{
|
||
responeTraFransfersFile = new ResponeTraFransfersFile(traFransfersFile.MD5, size, -2);
|
||
Send((int)Command.ResponeSendFilePack, responeTraFransfersFile, remoteEp);
|
||
}
|
||
else
|
||
{
|
||
responeTraFransfersFile = new ResponeTraFransfersFile(traFransfersFile.MD5, size, receiveFileManager.GetNextReceiveIndex());
|
||
Send((int)Command.ResponeSendFilePack, responeTraFransfersFile, remoteEp);
|
||
}
|
||
OnFileReceiveBuffer(new FileReceiveBufferEventArgs(receiveFileManager, traFransfersFile.Buffer.Length));
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 开始接收文件事件方法(尚未开始接收文件)
|
||
/// <summary>
|
||
/// 开始接收文件事件方法(尚未开始接收文件)
|
||
/// </summary>
|
||
/// <param name="traFransfersFileStart"></param>
|
||
/// <param name="remoteEp"></param>
|
||
private void OnStartRecieve(TraFransfersFileStart traFransfersFileStart, IPEndPoint remoteEp)
|
||
{
|
||
OnFileRecieveRequest(new RequestSendFileEventArgs(traFransfersFileStart, remoteEp));
|
||
}
|
||
#endregion
|
||
|
||
|
||
#endregion
|
||
|
||
#region 接受原始数据事件
|
||
public delegate void ReceiveByteEventHandler(ReceiveDataEventArgs e);
|
||
[Description("接收文本数据事件")]
|
||
public event ReceiveByteEventHandler ReceiveByte;
|
||
/// <summary>
|
||
/// 文件被接收时触发事件
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected virtual void OnReceiveByte(ReceiveDataEventArgs e)
|
||
{
|
||
ReceiveByte?.Invoke(e);
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region FileTransfersItem子项
|
||
|
||
#region Items变量
|
||
private Color _baseColor = Color.FromArgb(255, 192, 128);
|
||
private Color _borderColor = Color.FromArgb(224, 224, 224);
|
||
private Color _progressBarBarColor = Color.SteelBlue;
|
||
private Color _progressBarBorderColor = Color.LightGray;
|
||
private Color _progressBarTextColor = Color.White;
|
||
#endregion
|
||
|
||
#region 接收文件子项控件
|
||
|
||
/// <summary>
|
||
/// 添加准备接收文件Item
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
public void AddReadyReceiveItem(RequestSendFileEventArgs e)
|
||
{
|
||
TraFransfersFileStart traFransfersFileStart = e.TraFransfersFileStart;
|
||
|
||
Form.ActiveForm.BeginInvoke(new MethodInvoker(delegate ()
|
||
{
|
||
FileTransfersItem item = fileTansfersContainer.AddItem(traFransfersFileStart.MD5, "接收文件", traFransfersFileStart.FileName, traFransfersFileStart.Image, traFransfersFileStart.Length, FileTransfersItemStyle.ReadyReceive);
|
||
|
||
item.BaseColor = _baseColor;
|
||
item.BorderColor = _borderColor;
|
||
item.ProgressBarBarColor = _progressBarBarColor;
|
||
item.ProgressBarBorderColor = _progressBarBorderColor;
|
||
item.ProgressBarTextColor = _progressBarTextColor;
|
||
item.Tag = e;
|
||
item.SaveButtonClick += new EventHandler(ItemSaveButtonClick);
|
||
item.SaveToButtonClick += new EventHandler(ItemSaveToButtonClick);
|
||
item.RefuseButtonClick += new EventHandler(ItemRefuseButtonClick);
|
||
fileTansfersContainer.ResumeLayout(true);
|
||
}));
|
||
|
||
}
|
||
|
||
#region 按钮事件
|
||
/// <summary>
|
||
/// 文件另存为按钮事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void ItemSaveToButtonClick(object sender, EventArgs e)
|
||
{
|
||
FileTransfersItem item = sender as FileTransfersItem;
|
||
RequestSendFileEventArgs rse = item.Tag as RequestSendFileEventArgs;
|
||
FolderBrowserDialog fbd = new FolderBrowserDialog();
|
||
if (fbd.ShowDialog() == DialogResult.OK)
|
||
{
|
||
rse.Path = fbd.SelectedPath;
|
||
ControlTag tag = new ControlTag(rse.TraFransfersFileStart.MD5, rse.TraFransfersFileStart.FileName, rse.RemoteIP);
|
||
item.Tag = tag;
|
||
item.Style = FileTransfersItemStyle.Receive;
|
||
item.CancelButtonClick += new EventHandler(ItemCancelButtonClick);
|
||
item.Start();
|
||
|
||
this.AcceptReceive(rse);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存文件按钮事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void ItemSaveButtonClick(object sender, EventArgs e)
|
||
{
|
||
FileTransfersItem item = sender as FileTransfersItem;
|
||
RequestSendFileEventArgs rse = item.Tag as RequestSendFileEventArgs;
|
||
//自动保存在程序根目录下
|
||
rse.Path = Application.StartupPath;
|
||
ControlTag tag = new ControlTag(rse.TraFransfersFileStart.MD5, rse.TraFransfersFileStart.FileName, rse.RemoteIP);
|
||
item.Tag = tag;
|
||
item.Style = FileTransfersItemStyle.Receive;
|
||
item.CancelButtonClick += new EventHandler(ItemCancelButtonClick);
|
||
item.Start();
|
||
this.AcceptReceive(rse);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拒绝接收文件按钮事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void ItemRefuseButtonClick(object sender, EventArgs e)
|
||
{
|
||
FileTransfersItem item = sender as FileTransfersItem;
|
||
RequestSendFileEventArgs rse = item.Tag as RequestSendFileEventArgs;
|
||
rse.Cancel = true;
|
||
fileTansfersContainer.RemoveItem(item);
|
||
item.Dispose();
|
||
AcceptReceive(rse);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消按钮事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void ItemCancelButtonClick(object sender, EventArgs e)
|
||
{
|
||
FileTransfersItem item = sender as FileTransfersItem;
|
||
ControlTag tag = item.Tag as ControlTag;
|
||
CancelReceive(tag.MD5, tag.RemoteIP);
|
||
fileTansfersContainer.RemoveItem(item);
|
||
item.Dispose();
|
||
}
|
||
#endregion
|
||
#endregion
|
||
|
||
#region 发送文件子项控件
|
||
/// <summary>
|
||
/// 添加发送文件控件Item
|
||
/// </summary>
|
||
/// <param name="sendFileManager"></param>
|
||
/// <param name="image"></param>
|
||
public void AddSendItems(SendFileManager sendFileManager, Image image)
|
||
{
|
||
|
||
FileTransfersItem item = fileTansfersContainer.AddItem(sendFileManager.MD5, "发送文件", sendFileManager.Name, image, sendFileManager.Length, FileTransfersItemStyle.Send);
|
||
item.BaseColor = Color.FromArgb(224, 224, 224);
|
||
item.BorderColor = _borderColor;
|
||
item.ProgressBarBarColor = _progressBarBarColor;
|
||
item.ProgressBarBorderColor = _progressBarBorderColor;
|
||
item.ProgressBarTextColor = _progressBarTextColor;
|
||
item.CancelButtonClick += new EventHandler(ItemSendCancelButtonClick);
|
||
item.Tag = sendFileManager;
|
||
sendFileManager.Tag = item;
|
||
}
|
||
#region 按钮事件
|
||
|
||
private void ItemSendCancelButtonClick(object sender, EventArgs e)
|
||
{
|
||
FileTransfersItem item = sender as FileTransfersItem;
|
||
SendFileManager sendFileManager = item.Tag as SendFileManager;
|
||
this.CancelSend(sendFileManager.MD5);
|
||
|
||
fileTansfersContainer.RemoveItem(item);
|
||
}
|
||
|
||
#endregion
|
||
#endregion
|
||
#endregion
|
||
}
|
||
}
|