初始化版本

This commit is contained in:
LL
2025-11-14 16:12:32 +08:00
commit ea40f18aa6
326 changed files with 137063 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
namespace NetWorkHelper
{
partial class AxUdpClient
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.fileTansfersContainer = new NetWorkHelper.FileTansfersContainer();
//
// fileTansfersContainer
//
this.fileTansfersContainer.AutoScroll = true;
this.fileTansfersContainer.Location = new System.Drawing.Point(0, 0);
this.fileTansfersContainer.Name = "fileTansfersContainer";
this.fileTansfersContainer.Size = new System.Drawing.Size(200, 100);
this.fileTansfersContainer.TabIndex = 0;
}
#endregion
private FileTansfersContainer fileTansfersContainer;
}
}

View File

@@ -0,0 +1,959 @@
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
}
}

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="fileTansfersContainer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,10 @@
namespace NetWorkHelper
{
internal enum ControlState
{
Normal,
Hover,
Pressed,
Focused
}
}

View File

@@ -0,0 +1,162 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace NetWorkHelper
{
/// <summary>
/// <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public class FileTansfersContainer : Panel
{
private IFileTransfersItemText _fileTransfersItemText;
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IFileTransfersItemText FileTransfersItemText
{
get
{
if (this._fileTransfersItemText == null)
{
this._fileTransfersItemText = new FileTransfersItemText();
}
return this._fileTransfersItemText;
}
set
{
this._fileTransfersItemText = value;
foreach (FileTransfersItem item in base.Controls)
{
item.FileTransfersText = this._fileTransfersItemText;
}
}
}
public FileTansfersContainer()
{
this.AutoScroll = true;
}
private bool _isAutomaticShowHide = true;
[Description("<22>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ؿؼ<D8BF>\r\n(trueΪ<65><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʱ<EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ؿؼ<D8BF>)")]
public bool IsAutomaticShowHide
{
get { return _isAutomaticShowHide; }
set { _isAutomaticShowHide = value; }
}
public FileTransfersItem AddItem(string text, string fileName, Image image, long fileSize, FileTransfersItemStyle style)
{
FileTransfersItem item = new FileTransfersItem();
item.Text = text;
item.FileName = fileName;
item.Image = image;
item.FileSize = fileSize;
item.Style = style;
item.FileTransfersText = this.FileTransfersItemText;
item.Dock = DockStyle.Top;
base.SuspendLayout();
base.Controls.Add(item);
item.BringToFront();
base.ResumeLayout(true);
if (IsAutomaticShowHide)
{
base.Visible = base.Controls.Count > 0 ? true : false;
}
return item;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>FileTransfersItem<65>ļ<EFBFBD><C4BC><EFBFBD>
/// </summary>
/// <param name="md5"><3E><><EFBFBD>ƣ<EFBFBD>MD5У<35><D0A3>ֵ<EFBFBD><D6B5></param>
/// <param name="typetext"><3E>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD></param>
/// <param name="fileName"><3E>ļ<EFBFBD>·<EFBFBD><C2B7></param>
/// <param name="image"><3E>ļ<EFBFBD>ͼ<EFBFBD><CDBC></param>
/// <param name="fileSize"><3E>ļ<EFBFBD><C4BC><EFBFBD>С</param>
/// <param name="style"><3E>ļ<EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9BFB4>FileTransfersItemStyle<6C><65></param>
/// <returns></returns>
public FileTransfersItem AddItem(string md5, string typetext, string fileName, Image image, long fileSize, FileTransfersItemStyle style)
{
FileTransfersItem item = new FileTransfersItem();
item.Name = md5;
item.Text = typetext;
item.FileName = fileName;
item.Image = image;
item.FileSize = fileSize;
item.Style = style;
item.FileTransfersText = this.FileTransfersItemText;
item.Dock = DockStyle.Top;
base.SuspendLayout();
base.Controls.Add(item);
item.BringToFront();
base.ResumeLayout(true);
if (IsAutomaticShowHide)
{
base.Visible = base.Controls.Count > 0 ? true : false;
}
return item;
}
/// <summary>
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD>ӦFileTransfersItem
/// </summary>
/// <param name="item">FileTransfersItem</param>
public void RemoveItem(FileTransfersItem item)
{
base.Controls.Remove(item);
if (IsAutomaticShowHide)
{
base.Visible = base.Controls.Count > 0 ? true : false;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>MD5<44><35>ֵ<EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD>Ӧ<EFBFBD>ؼ<EFBFBD>
/// </summary>
/// <param name="md5"></param>
public void RemoveItem(string md5)
{
base.Controls.RemoveByKey(md5);
if (IsAutomaticShowHide)
{
base.Visible = base.Controls.Count > 0 ? true : false;
}
}
public void RemoveItem(Predicate<FileTransfersItem> match)
{
FileTransfersItem itemRemove = null;
foreach (FileTransfersItem item in base.Controls)
{
if (match(item))
{
itemRemove = item;
}
}
base.Controls.Remove(itemRemove);
if (IsAutomaticShowHide)
{
base.Visible = base.Controls.Count > 0 ? true : false;
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>MD5У<35><D0A3>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>FileTransfersItem
/// </summary>
/// <param name="md5"></param>
/// <returns></returns>
public FileTransfersItem Search(string md5)
{
return base.Controls[md5] as FileTransfersItem;
}
public FileTransfersItem Search(Predicate<FileTransfersItem> match)
{
FileTransfersItem result;
foreach (FileTransfersItem item in base.Controls)
{
if (match(item))
{
result = item;
return result;
}
}
result = null;
return result;
}
}
}

View File

@@ -0,0 +1,986 @@
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
namespace NetWorkHelper
{
public class FileTransfersItem : Control
{
private Image _image;
private string _fileName;
private long _fileSize;
private long _totalTransfersSize;
private FileTransfersItemStyle _style;
private RoundStyle _roundStyle = RoundStyle.All;
private int _radius = 8;
private Color _baseColor = Color.FromArgb(191, 233, 255);
private Color _borderColor = Color.FromArgb(118, 208, 225);
private Color _progressBarTrackColor = Color.Gainsboro;
private Color _progressBarBarColor = Color.FromArgb(191, 233, 255);
private Color _progressBarBorderColor = Color.FromArgb(118, 208, 225);
private Color _progressBarTextColor = Color.FromArgb(0, 95, 147);
private int _interval = 1000;
private IFileTransfersItemText _fileTransfersText;
private DateTime _startTime = DateTime.Now;
private System.Threading.Timer _timer;
private ControlState _saveState;
private ControlState _saveToState;
private ControlState _refuseState;
private ControlState _cancelState;
private static readonly object EventSaveButtonClick = new object();
private static readonly object EventSaveToButtonClick = new object();
private static readonly object EventRefuseButtonClick = new object();
private static readonly object EventCancelButtonClick = new object();
public event EventHandler SaveButtonClick
{
add
{
base.Events.AddHandler(FileTransfersItem.EventSaveButtonClick, value);
}
remove
{
base.Events.RemoveHandler(FileTransfersItem.EventSaveButtonClick, value);
}
}
public event EventHandler SaveToButtonClick
{
add
{
base.Events.AddHandler(FileTransfersItem.EventSaveToButtonClick, value);
}
remove
{
base.Events.RemoveHandler(FileTransfersItem.EventSaveToButtonClick, value);
}
}
public event EventHandler RefuseButtonClick
{
add
{
base.Events.AddHandler(FileTransfersItem.EventRefuseButtonClick, value);
}
remove
{
base.Events.RemoveHandler(FileTransfersItem.EventRefuseButtonClick, value);
}
}
public event EventHandler CancelButtonClick
{
add
{
base.Events.AddHandler(FileTransfersItem.EventCancelButtonClick, value);
}
remove
{
base.Events.RemoveHandler(FileTransfersItem.EventCancelButtonClick, value);
}
}
[DefaultValue(typeof(Icon), "null")]
public Image Image
{
get
{
return this._image;
}
set
{
this._image = value;
base.Invalidate();
}
}
[DefaultValue("")]
public string FileName
{
get
{
return this._fileName;
}
set
{
this._fileName = value;
base.Invalidate();
}
}
[DefaultValue(0)]
public long FileSize
{
get
{
return this._fileSize;
}
set
{
this._fileSize = value;
base.Invalidate();
}
}
[DefaultValue(0)]
public long TotalTransfersSize
{
get
{
return this._totalTransfersSize;
}
set
{
if (this._totalTransfersSize != value)
{
if (value > this._fileSize)
{
this._totalTransfersSize = this._fileSize;
}
else
{
this._totalTransfersSize = value;
}
base.Invalidate(this.ProgressBarRect);
base.Invalidate(this.TransfersSizeRect);
}
}
}
[DefaultValue(typeof(FileTransfersItemStyle), "0")]
public FileTransfersItemStyle Style
{
get
{
return this._style;
}
set
{
this._style = value;
base.Invalidate();
}
}
[DefaultValue(typeof(RoundStyle), "1")]
public RoundStyle RoundStyle
{
get
{
return this._roundStyle;
}
set
{
if (this._roundStyle != value)
{
this._roundStyle = value;
base.Invalidate();
}
}
}
[DefaultValue(8)]
public int Radius
{
get
{
return this._radius;
}
set
{
if (this._radius != value)
{
this._radius = ((value < 1) ? 1 : value);
base.Invalidate();
}
}
}
[DefaultValue(typeof(Color), "191, 233, 255")]
public Color BaseColor
{
get
{
return this._baseColor;
}
set
{
this._baseColor = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "118, 208, 225")]
public Color BorderColor
{
get
{
return this._borderColor;
}
set
{
this._borderColor = value;
base.Invalidate();
}
}
[DefaultValue(typeof(Color), "Gainsboro")]
public Color ProgressBarTrackColor
{
get
{
return this._progressBarTrackColor;
}
set
{
this._progressBarTrackColor = value;
base.Invalidate(this.ProgressBarRect);
}
}
[DefaultValue(typeof(Color), "191, 233, 255")]
public Color ProgressBarBarColor
{
get
{
return this._progressBarBarColor;
}
set
{
this._progressBarBarColor = value;
base.Invalidate(this.ProgressBarRect);
}
}
[DefaultValue(typeof(Color), "118, 208, 225")]
public Color ProgressBarBorderColor
{
get
{
return this._progressBarBorderColor;
}
set
{
this._progressBarBorderColor = value;
base.Invalidate(this.ProgressBarRect);
}
}
[DefaultValue(typeof(Color), "0, 95, 147")]
public Color ProgressBarTextColor
{
get
{
return this._progressBarTextColor;
}
set
{
this._progressBarTextColor = value;
base.Invalidate(this.ProgressBarRect);
}
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IFileTransfersItemText FileTransfersText
{
get
{
if (this._fileTransfersText == null)
{
this._fileTransfersText = new FileTransfersItemText();
}
return this._fileTransfersText;
}
set
{
this._fileTransfersText = value;
base.Invalidate();
}
}
[DefaultValue(1000)]
public int Interval
{
get
{
return this._interval;
}
set
{
this._interval = value;
}
}
internal System.Threading.Timer Timer
{
get
{
if (this._timer == null)
{
this._timer = new System.Threading.Timer(delegate (object obj)
{
if (!base.Disposing)
{
if (!base.Disposing)
{
base.BeginInvoke((MethodInvoker)delegate ()
{
base.Invalidate(this.SpeedRect);
});
}
}
}, null, -1, this._interval);
//System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(timer_Elapsed), null, -1, this._interval);
}
return this._timer;
}
}
internal Rectangle ImageRect
{
get
{
return new Rectangle(6, 6, 32, 32);
}
}
internal Rectangle TextRect
{
get
{
return new Rectangle(43, 6, base.Width - 49, 16);
}
}
internal Rectangle FileNameRect
{
get
{
return new Rectangle(43, 22, base.Width - 49, 16);
}
}
internal Rectangle ProgressBarRect
{
get
{
return new Rectangle(4, 41, base.Width - 8, 16);
}
}
internal Rectangle SpeedRect
{
get
{
return new Rectangle(6, 60, base.Width / 2 - 8, 16);
}
}
internal Rectangle TransfersSizeRect
{
get
{
return new Rectangle(base.Width / 2, 60, base.Width / 2 - 6, 16);
}
}
internal Rectangle RefuseReceiveRect
{
get
{
Size size = TextRenderer.MeasureText(this.FileTransfersText.RefuseReceive, this.Font);
return new Rectangle(base.Width - size.Width - 7, 79, size.Width, size.Height);
}
}
internal Rectangle CancelTransfersRect
{
get
{
Size size = TextRenderer.MeasureText(this.FileTransfersText.CancelTransfers, this.Font);
return new Rectangle(base.Width - size.Width - 7, 79, size.Width, size.Height);
}
}
internal Rectangle SaveToRect
{
get
{
Size size = TextRenderer.MeasureText(this.FileTransfersText.SaveTo, this.Font);
return new Rectangle(this.RefuseReceiveRect.X - size.Width - 20, 79, size.Width, size.Height);
}
}
internal Rectangle SaveRect
{
get
{
Size size = TextRenderer.MeasureText(this.FileTransfersText.Save, this.Font);
return new Rectangle(this.SaveToRect.X - size.Width - 20, 79, size.Width, size.Height);
}
}
protected override Size DefaultSize
{
get
{
return new Size(200, 97);
}
}
private ControlState SaveState
{
get
{
return this._saveState;
}
set
{
if (this._saveState != value)
{
this._saveState = value;
base.Invalidate(this.Inflate(this.SaveRect));
}
}
}
private ControlState SaveToState
{
get
{
return this._saveToState;
}
set
{
if (this._saveToState != value)
{
this._saveToState = value;
base.Invalidate(this.Inflate(this.SaveToRect));
}
}
}
private ControlState RefuseState
{
get
{
return this._refuseState;
}
set
{
if (this._refuseState != value)
{
this._refuseState = value;
base.Invalidate(this.Inflate(this.RefuseReceiveRect));
}
}
}
private ControlState CancelState
{
get
{
return this._cancelState;
}
set
{
if (this._cancelState != value)
{
this._cancelState = value;
base.Invalidate(this.Inflate(this.CancelTransfersRect));
}
}
}
public FileTransfersItem()
{
this.SetStyles();
}
public void Start()
{
this._startTime = DateTime.Now;
this.Timer.Change(this._interval, this._interval);
}
protected virtual void OnSaveButtonClick(EventArgs e)
{
EventHandler handler = base.Events[FileTransfersItem.EventSaveButtonClick] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnSaveToButtonClick(EventArgs e)
{
EventHandler handler = base.Events[FileTransfersItem.EventSaveToButtonClick] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnRefuseButtonClick(EventArgs e)
{
EventHandler handler = base.Events[FileTransfersItem.EventRefuseButtonClick] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
protected virtual void OnCancelButtonClick(EventArgs e)
{
EventHandler handler = base.Events[FileTransfersItem.EventCancelButtonClick] as EventHandler;
if (handler != null)
{
handler(this, e);
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
Point point = e.Location;
switch (this._style)
{
case FileTransfersItemStyle.Send:
case FileTransfersItemStyle.Receive:
if (this.CancelTransfersRect.Contains(point))
{
this.CancelState = ControlState.Hover;
}
else
{
this.CancelState = ControlState.Normal;
}
break;
case FileTransfersItemStyle.ReadyReceive:
if (this.SaveRect.Contains(point))
{
this.SaveState = ControlState.Hover;
}
else
{
this.SaveState = ControlState.Normal;
}
if (this.SaveToRect.Contains(point))
{
this.SaveToState = ControlState.Hover;
}
else
{
this.SaveToState = ControlState.Normal;
}
if (this.RefuseReceiveRect.Contains(point))
{
this.RefuseState = ControlState.Hover;
}
else
{
this.RefuseState = ControlState.Normal;
}
break;
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
Point point = e.Location;
switch (this._style)
{
case FileTransfersItemStyle.Send:
case FileTransfersItemStyle.Receive:
if (this.CancelTransfersRect.Contains(point))
{
this.CancelState = ControlState.Pressed;
}
break;
case FileTransfersItemStyle.ReadyReceive:
if (this.SaveRect.Contains(point))
{
this.SaveState = ControlState.Pressed;
}
if (this.SaveToRect.Contains(point))
{
this.SaveToState = ControlState.Pressed;
}
if (this.RefuseReceiveRect.Contains(point))
{
this.RefuseState = ControlState.Pressed;
}
break;
}
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
if (e.Button == MouseButtons.Left)
{
Point point = e.Location;
switch (this._style)
{
case FileTransfersItemStyle.Send:
case FileTransfersItemStyle.Receive:
if (this.CancelTransfersRect.Contains(point))
{
this.CancelState = ControlState.Hover;
this.OnCancelButtonClick(e);
}
else
{
this.CancelState = ControlState.Normal;
}
break;
case FileTransfersItemStyle.ReadyReceive:
if (this.SaveRect.Contains(point))
{
this.SaveState = ControlState.Hover;
this.OnSaveButtonClick(e);
}
else
{
this.SaveState = ControlState.Normal;
}
if (this.SaveToRect.Contains(point))
{
this.SaveToState = ControlState.Hover;
this.OnSaveToButtonClick(e);
}
else
{
this.SaveToState = ControlState.Normal;
}
if (this.RefuseReceiveRect.Contains(point))
{
this.RefuseState = ControlState.Hover;
this.OnRefuseButtonClick(e);
}
else
{
this.RefuseState = ControlState.Normal;
}
break;
}
}
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
switch (this._style)
{
case FileTransfersItemStyle.Send:
case FileTransfersItemStyle.Receive:
this.CancelState = ControlState.Normal;
break;
case FileTransfersItemStyle.ReadyReceive:
this.SaveState = ControlState.Normal;
this.SaveToState = ControlState.Normal;
this.RefuseState = ControlState.Normal;
break;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
if (this.Image != null)
{
g.DrawImage(this.Image, this.ImageRect, new Rectangle(Point.Empty, this.Image.Size), GraphicsUnit.Pixel);
}
TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.SingleLine;
TextRenderer.DrawText(g, this.Text, this.Font, this.TextRect, this.ForeColor, flags);
TextRenderer.DrawText(g, this.FileName, this.Font, this.FileNameRect, this.ForeColor, flags);
Rectangle rect = this.ProgressBarRect;
Color innerBorderColor = Color.FromArgb(200, 255, 255, 255);
this.RenderBackgroundInternal(g, rect, this._progressBarTrackColor, this._progressBarBorderColor, innerBorderColor, RoundStyle.None, 0, 0.0f, false, false, LinearGradientMode.Vertical);
if (this.FileSize != 0L)
{
float percent = (float)this.TotalTransfersSize / (float)this.FileSize;
int width = (int)((float)rect.Width * percent);
width = Math.Min(width, rect.Width - 2);
if (width > 5)
{
Rectangle barRect = new Rectangle(rect.X + 1, rect.Y + 1, width, rect.Height - 2);
this.RenderBackgroundInternal(g, barRect, this._progressBarBarColor, this._progressBarBarColor, innerBorderColor, RoundStyle.None, 0, 0.0f, false, false, LinearGradientMode.Vertical);
}
TextRenderer.DrawText(g, percent.ToString("0.0%"), this.Font, rect, this._progressBarTextColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
string transferSizeText = string.Format("{0}/{1}", this.GetText((double)this._totalTransfersSize), this.GetText((double)this._fileSize));
TextRenderer.DrawText(g, transferSizeText, this.Font, this.TransfersSizeRect, this.ForeColor, TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
if (this._totalTransfersSize != 0L && !base.DesignMode)
{
TextRenderer.DrawText(g, this.GetSpeedText(), this.Font, this.SpeedRect, this.ForeColor, TextFormatFlags.VerticalCenter);
}
}
flags = (TextFormatFlags.EndEllipsis | TextFormatFlags.HorizontalCenter | TextFormatFlags.SingleLine);
switch (this._style)
{
case FileTransfersItemStyle.Send:
case FileTransfersItemStyle.Receive:
if (this.CancelState != ControlState.Normal)
{
rect = this.CancelTransfersRect;
rect.Inflate(2, 2);
this.RenderBackgroundInternal(g, rect, this._baseColor, this._borderColor, innerBorderColor, RoundStyle.None, this._radius, 0.0f, true, true, LinearGradientMode.Vertical);
}
TextRenderer.DrawText(g, this.FileTransfersText.CancelTransfers, this.Font, this.CancelTransfersRect, this.ForeColor, flags);
break;
case FileTransfersItemStyle.ReadyReceive:
{
bool drawBack = false;
if (this.SaveState != ControlState.Normal)
{
rect = this.SaveRect;
rect.Inflate(2, 2);
drawBack = true;
}
if (this.SaveToState != ControlState.Normal)
{
rect = this.SaveToRect;
rect.Inflate(2, 2);
drawBack = true;
}
if (this.RefuseState != ControlState.Normal)
{
rect = this.RefuseReceiveRect;
rect.Inflate(2, 2);
drawBack = true;
}
if (drawBack)
{
this.RenderBackgroundInternal(g, rect, this._baseColor, this._borderColor, innerBorderColor, RoundStyle.None, this._radius, 0.45f, true, true, LinearGradientMode.Vertical);
}
TextRenderer.DrawText(g, this.FileTransfersText.RefuseReceive, this.Font, this.RefuseReceiveRect, this.ForeColor, flags);
TextRenderer.DrawText(g, this.FileTransfersText.SaveTo, this.Font, this.SaveToRect, this.ForeColor, flags);
TextRenderer.DrawText(g, this.FileTransfersText.Save, this.Font, this.SaveRect, this.ForeColor, flags);
break;
}
}
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Graphics g = e.Graphics;
Rectangle rect = base.ClientRectangle;
g.SmoothingMode = SmoothingMode.AntiAlias;
rect.Inflate(-1, -1);
this.RenderBackgroundInternal(g, rect, this._baseColor, this._borderColor, Color.FromArgb(200, 255, 255), this._roundStyle, this._radius, 0.45f, true, false, LinearGradientMode.Vertical);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
if (this._timer != null)
{
this._timer.Dispose();
}
this._fileTransfersText = null;
}
}
private void SetStyles()
{
base.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.FixedHeight | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
base.SetStyle(ControlStyles.Opaque, false);
base.UpdateStyles();
}
internal void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor, RoundStyle style, int roundWidth, float basePosition, bool drawBorder, bool drawGlass, LinearGradientMode mode)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
if (rect.Width > 0 && rect.Height > 0)
{
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
{
Color[] colors = new Color[]
{
this.GetColor(baseColor, 0, 35, 24, 9),
this.GetColor(baseColor, 0, 13, 8, 3),
baseColor,
this.GetColor(baseColor, 0, 68, 69, 54)
};
brush.InterpolationColors = new ColorBlend
{
Positions = new float[]
{
0f,
basePosition,
basePosition + 0.05f,
1f
},
Colors = colors
};
if (style != RoundStyle.None)
{
using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
{
g.FillPath(brush, path);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)((float)rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)((float)rect.Width * basePosition);
}
using (GraphicsPath pathTop = GraphicsPathHelper.CreatePath(rectTop, roundWidth, RoundStyle.Top, false))
{
using (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillPath(brushAlpha, pathTop);
}
}
}
if (drawGlass)
{
RectangleF glassRect = rect;
if (mode == LinearGradientMode.Vertical)
{
glassRect.Y = (float)rect.Y + (float)rect.Height * basePosition;
glassRect.Height = ((float)rect.Height - (float)rect.Height * basePosition) * 2f;
}
else
{
glassRect.X = (float)rect.X + (float)rect.Width * basePosition;
glassRect.Width = ((float)rect.Width - (float)rect.Width * basePosition) * 2f;
}
this.DrawGlass(g, glassRect, 170, 0);
}
if (drawBorder)
{
using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
{
using (Pen pen = new Pen(borderColor))
{
g.DrawPath(pen, path);
}
}
rect.Inflate(-1, -1);
using (GraphicsPath path = GraphicsPathHelper.CreatePath(rect, roundWidth, style, false))
{
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawPath(pen, path);
}
}
}
}
else
{
g.FillRectangle(brush, rect);
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)((float)rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)((float)rect.Width * basePosition);
}
using (SolidBrush brushAlpha = new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawGlass)
{
RectangleF glassRect = rect;
if (mode == LinearGradientMode.Vertical)
{
glassRect.Y = (float)rect.Y + (float)rect.Height * basePosition;
glassRect.Height = ((float)rect.Height - (float)rect.Height * basePosition) * 2f;
}
else
{
glassRect.X = (float)rect.X + (float)rect.Width * basePosition;
glassRect.Width = ((float)rect.Width - (float)rect.Width * basePosition) * 2f;
}
this.DrawGlass(g, glassRect, 200, 0);
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
}
}
}
private void DrawGlass(Graphics g, RectangleF glassRect, int alphaCenter, int alphaSurround)
{
this.DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround);
}
private void DrawGlass(Graphics g, RectangleF glassRect, Color glassColor, int alphaCenter, int alphaSurround)
{
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(glassRect);
using (PathGradientBrush brush = new PathGradientBrush(path))
{
brush.CenterColor = Color.FromArgb(alphaCenter, glassColor);
brush.SurroundColors = new Color[]
{
Color.FromArgb(alphaSurround, glassColor)
};
brush.CenterPoint = new PointF(glassRect.X + glassRect.Width / 2f, glassRect.Y + glassRect.Height / 2f);
g.FillPath(brush, path);
}
}
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a2 = (int)colorBase.A;
int r2 = (int)colorBase.R;
int g2 = (int)colorBase.G;
int b2 = (int)colorBase.B;
if (a + a2 > 255)
{
a = 255;
}
else
{
a = Math.Max(a + a2, 0);
}
if (r + r2 > 255)
{
r = 255;
}
else
{
r = Math.Max(r + r2, 0);
}
if (g + g2 > 255)
{
g = 255;
}
else
{
g = Math.Max(g + g2, 0);
}
if (b + b2 > 255)
{
b = 255;
}
else
{
b = Math.Max(b + b2, 0);
}
return Color.FromArgb(a, r, g, b);
}
private string GetText(double size)
{
string result;
if (size < 1024.0)
{
result = string.Format("{0} B", size.ToString("f1"));
}
else
{
if (size < 1048576.0)
{
result = string.Format("{0} KB", (size / 1024.0).ToString("f1"));
}
else
{
result = string.Format("{0} MB", (size / 1048576.0).ToString("f1"));
}
}
return result;
}
private string GetSpeedText()
{
TimeSpan span = DateTime.Now - this._startTime;
double speed = (double)this._totalTransfersSize / span.TotalSeconds;
return string.Format("{0}/s", this.GetText(speed));
}
private Rectangle Inflate(Rectangle rect)
{
rect.Inflate(2, 2);
return rect;
}
}
}

View File

@@ -0,0 +1,21 @@
namespace NetWorkHelper
{
/// <summary>
/// <20>ļ<EFBFBD>״̬
/// </summary>
public enum FileTransfersItemStyle
{
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
/// </summary>
Send,
/// <summary>
/// ׼<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
/// </summary>
ReadyReceive,
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
/// </summary>
Receive
}
}

View File

@@ -0,0 +1,34 @@
namespace NetWorkHelper
{
internal class FileTransfersItemText : IFileTransfersItemText
{
public string Save
{
get
{
return "接收";
}
}
public string SaveTo
{
get
{
return "另存为...";
}
}
public string RefuseReceive
{
get
{
return "拒绝";
}
}
public string CancelTransfers
{
get
{
return "取消";
}
}
}
}

View File

@@ -0,0 +1,47 @@
using System.Drawing;
using System.Drawing.Drawing2D;
namespace NetWorkHelper
{
public static class GraphicsPathHelper
{
public static GraphicsPath CreatePath(Rectangle rect, int radius, RoundStyle style, bool correction)
{
GraphicsPath path = new GraphicsPath();
int radiusCorrection = correction ? 1 : 0;
switch (style)
{
case RoundStyle.None:
path.AddRectangle(rect);
break;
case RoundStyle.All:
path.AddArc(rect.X, rect.Y, radius, radius, 180f, 90f);
path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270f, 90f);
path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0f, 90f);
path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90f, 90f);
break;
case RoundStyle.Left:
path.AddArc(rect.X, rect.Y, radius, radius, 180f, 90f);
path.AddLine(rect.Right - radiusCorrection, rect.Y, rect.Right - radiusCorrection, rect.Bottom - radiusCorrection);
path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90f, 90f);
break;
case RoundStyle.Right:
path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270f, 90f);
path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0f, 90f);
path.AddLine(rect.X, rect.Bottom - radiusCorrection, rect.X, rect.Y);
break;
case RoundStyle.Top:
path.AddArc(rect.X, rect.Y, radius, radius, 180f, 90f);
path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270f, 90f);
path.AddLine(rect.Right - radiusCorrection, rect.Bottom - radiusCorrection, rect.X, rect.Bottom - radiusCorrection);
break;
case RoundStyle.Bottom:
path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0f, 90f);
path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90f, 90f);
path.AddLine(rect.X, rect.Y, rect.Right - radiusCorrection, rect.Y);
break;
}
path.CloseFigure();
return path;
}
}
}

View File

@@ -0,0 +1,22 @@
namespace NetWorkHelper
{
public interface IFileTransfersItemText
{
string Save
{
get;
}
string SaveTo
{
get;
}
string RefuseReceive
{
get;
}
string CancelTransfers
{
get;
}
}
}

View File

@@ -0,0 +1,12 @@
namespace NetWorkHelper
{
public enum RoundStyle
{
None,
All,
Left,
Right,
Top,
Bottom
}
}

View File

@@ -0,0 +1,37 @@
using System;
namespace NetWorkHelper
{
[Serializable]
public class TraFransfersFile
{
private string _md5;
private int _index;
private byte[] _buffer;
public TraFransfersFile(string md5, int index, byte[] buffer)
{
_md5 = md5;
_index = index;
_buffer = buffer;
}
public string MD5
{
get { return _md5; }
set { _md5 = value; }
}
public int Index
{
get { return _index; }
set { _index = value; }
}
public byte[] Buffer
{
get { return _buffer; }
set { _buffer = value; }
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -0,0 +1,68 @@
using System;
using System.Drawing;
namespace NetWorkHelper
{
[Serializable]
public class TraFransfersFileStart
{
private string _md5;
private string _fileName;
private Image _image;
private long _length;
private long _partCount;
private int _partSize;
public TraFransfersFileStart(
string md5,
string fileName,
Image image,
long length,
long partCount,
int partSize)
{
_md5 = md5;
_fileName = fileName;
_image = image;
_length = length;
_partCount = partCount;
_partSize = partSize;
}
public string MD5
{
get { return _md5; }
set { _md5 = value; }
}
public Image Image
{
get { return _image; }
set { _image = value; }
}
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public long Length
{
get { return _length; }
set { _length = value; }
}
public long PartCount
{
get { return _partCount; }
set { _partCount = value; }
}
public int PartSize
{
get { return _partSize; }
set { _partSize = value; }
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace NetWorkHelper
{
public delegate void FileReceiveBufferEventHandler(object sender, FileReceiveBufferEventArgs e);
public class FileReceiveBufferEventArgs : EventArgs
{
public FileReceiveBufferEventArgs(ReceiveFileManager receiveFileManager, int size)
: base()
{
ReceiveFileManager = receiveFileManager;
Size = size;
}
public ReceiveFileManager ReceiveFileManager { get; }
public int Size { get; }
}
}

View File

@@ -0,0 +1,19 @@
using System;
namespace NetWorkHelper
{
public delegate void FileReceiveCompleteEventHandler(object sender, FileReceiveCompleteEventArgs e);
public class FileReceiveCompleteEventArgs : EventArgs
{
public FileReceiveCompleteEventArgs() { }
public FileReceiveCompleteEventArgs(bool success)
: base()
{
Success = success;
}
public bool Success { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace NetWorkHelper
{
public delegate void FileReceiveEventHandler(object sender, FileReceiveEventArgs e);
public class FileReceiveEventArgs : EventArgs
{
public FileReceiveEventArgs() { }
public FileReceiveEventArgs(ReceiveFileManager receiveFileManager) : base()
{
ReceiveFileManager = receiveFileManager;
}
public ReceiveFileManager ReceiveFileManager { get; }
public object Tag { get; set; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace NetWorkHelper
{
public delegate void FileSendBufferEventHandler(object sender, FileSendBufferEventArgs e);
public class FileSendBufferEventArgs : EventArgs
{
public FileSendBufferEventArgs(SendFileManager sendFileManager, int size)
: base()
{
SendFileManager = sendFileManager;
Size = size;
}
public SendFileManager SendFileManager { get; }
public int Size { get; }
}
}

View File

@@ -0,0 +1,17 @@
using System;
namespace NetWorkHelper
{
public delegate void FileSendEventHandler(object sender, FileSendEventArgs e);
public class FileSendEventArgs : EventArgs
{
public FileSendEventArgs(SendFileManager sendFileManager)
: base()
{
SendFileManager = sendFileManager;
}
public SendFileManager SendFileManager { get; }
}
}

View File

@@ -0,0 +1,20 @@
using System;
namespace NetWorkHelper
{
public delegate void ReadFileBufferEventHandler(object sender, ReadFileBufferEventArgs e);
public class ReadFileBufferEventArgs : EventArgs
{
public ReadFileBufferEventArgs(int index, byte[] buffer)
: base()
{
Index = index;
Buffer = buffer;
}
public int Index { get; }
public byte[] Buffer { get; }
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Net;
namespace NetWorkHelper
{
public delegate void ReceiveDataEventHandler(object sender, ReceiveDataEventArgs e);
public class ReceiveDataEventArgs : EventArgs
{
public ReceiveDataEventArgs() { }
public ReceiveDataEventArgs(byte[] buffer, IPEndPoint remoteIP)
: base()
{
Buffer = buffer;
RemoteIP = remoteIP;
}
public byte[] Buffer { get; set; }
public IPEndPoint RemoteIP { get; set; }
}
}

View File

@@ -0,0 +1,35 @@
using System.ComponentModel;
using System.Net;
namespace NetWorkHelper
{
public delegate void RequestSendFileEventHandler(object sender, RequestSendFileEventArgs e);
public class RequestSendFileEventArgs : CancelEventArgs
{
public RequestSendFileEventArgs()
: base()
{
}
public RequestSendFileEventArgs(TraFransfersFileStart traFransfersFileStart, IPEndPoint remoteIP)
: base()
{
TraFransfersFileStart = traFransfersFileStart;
RemoteIP = remoteIP;
}
public RequestSendFileEventArgs(TraFransfersFileStart traFransfersFileStart, IPEndPoint remoteIP, bool cancel)
: base(cancel)
{
TraFransfersFileStart = traFransfersFileStart;
RemoteIP = remoteIP;
}
public IPEndPoint RemoteIP { get; set; }
public TraFransfersFileStart TraFransfersFileStart { get; set; }
public string Path { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
namespace NetWorkHelper
{
/// <summary>
/// 消息数据单元接口
/// </summary>
public interface IDataCell
{
byte[] ToBuffer();
void FromBuffer(byte[] buffer);
}
}

View File

@@ -0,0 +1,16 @@

namespace NetWorkHelper
{
internal class ReadFileObject
{
public ReadFileObject(int index, byte[] buffer)
{
Index = index;
Buffer = buffer;
}
public int Index { get; set; }
public byte[] Buffer { get; set; }
}
}

View File

@@ -0,0 +1,238 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
namespace NetWorkHelper
{
public class ReceiveFileManager : IDisposable
{
#region Fields
private string _path;
private string _tempFileName;
private string _fullName;
private int _partSize;
private long _length;
private FileStream _fileStream;
private DateTime _lastReceiveTime;
private Timer _timer;
private int _interval = 5000;
private long _receivePartCount;
private static object SyncLock = new object();
private static readonly int ReceiveTimeout = 5000;
private static readonly string FileTemptName = ".tmp";
#endregion
#region Constructors
public ReceiveFileManager() { }
public ReceiveFileManager(string md5, string path, string fileName, long partCount, int partSize, long length, IPEndPoint remoteIP)
{
MD5 = md5;
_path = path;
Name = fileName;
PartCount = partCount;
_partSize = partSize;
_length = length;
RemoteIP = remoteIP;
Create();
}
#endregion
#region Events
public event FileReceiveCompleteEventHandler ReceiveFileComplete;
public event EventHandler ReceiveFileTimeout;
#endregion
#region Properties
public string MD5 { get; }
public long PartCount { get; }
public string Name { get; }
public string FileName
{
get
{
if (string.IsNullOrEmpty(_fullName))
{
GetFileName();
}
return _fullName;
}
}
public object Tag { get; set; }
public bool Success { get; private set; }
public IPEndPoint RemoteIP { get; }
public bool Completed
{
get { return PartCount == _receivePartCount; }
}
private Stream FileStream { get; set; }
private Dictionary<int, bool> ReceiveFilePartList { get; set; }
private Timer Timer
{
get
{
if (_timer == null)
{
_timer = new Timer(
new TimerCallback(delegate (object obj)
{
TimeSpan ts = DateTime.Now - _lastReceiveTime;
if (ts.TotalMilliseconds > ReceiveTimeout)
{
_lastReceiveTime = DateTime.Now;
OnReceiveFileTimeout(EventArgs.Empty);
}
}),
null,
Timeout.Infinite,
_interval);
}
return _timer;
}
}
#endregion
#region Methods
private void Create()
{
_tempFileName = string.Format("{0}\\{1}{2}", _path, Name, FileTemptName);
_fileStream = new FileStream(_tempFileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, _partSize * 10, true);
FileStream = Stream.Synchronized(_fileStream);
ReceiveFilePartList = new Dictionary<int, bool>();
for (int i = 0; i < PartCount; i++)
{
ReceiveFilePartList.Add(i, false);
}
}
public void Start()
{
_lastReceiveTime = DateTime.Now;
Timer.Change(0, _interval);
}
public int GetNextReceiveIndex()
{
foreach (int index in ReceiveFilePartList.Keys)
{
if (ReceiveFilePartList[index] == false)
{
return index;
}
}
return -1;
}
public int ReceiveBuffer(int index, byte[] buffer)
{
_lastReceiveTime = DateTime.Now;
if (ReceiveFilePartList[index])
{
return 0;
}
else
{
lock (SyncLock)
{
ReceiveFilePartList[index] = true;
_receivePartCount++;
}
FileStream.Position = index * _partSize;
FileStream.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(EndWrite), _receivePartCount);
return buffer.Length;
}
}
protected virtual void OnReceiveFileComplete(FileReceiveCompleteEventArgs e)
{
ReceiveFileComplete?.Invoke(this, e);
}
protected virtual void OnReceiveFileTimeout(EventArgs e)
{
ReceiveFileTimeout?.Invoke(this, e);
}
private void EndWrite(IAsyncResult result)
{
if (FileStream == null)
{
return;
}
FileStream.EndWrite(result);
long index = (long)result.AsyncState;
if (index == PartCount)
{
Dispose();
File.Move(_tempFileName, FileName);
Success = MD5 == MD5Helper.CretaeMD5(FileName);
OnReceiveFileComplete(new FileReceiveCompleteEventArgs(Success));
}
}
private void GetFileName()
{
_fullName = string.Format("{0}\\{1}", _path, Name);
int nameIndex = 1;
int index = Name.LastIndexOf('.');
while (File.Exists(_fullName))
{
_fullName = string.Format("{0}\\{1}", _path, Name.Insert(index, nameIndex.ToString("_0")));
nameIndex++;
}
}
#endregion
#region IDisposable
public void Dispose()
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
if (_fileStream != null)
{
FileStream.Flush();
FileStream.Close();
FileStream.Dispose();
FileStream = null;
_fileStream = null;
}
if (ReceiveFilePartList != null)
{
ReceiveFilePartList.Clear();
ReceiveFilePartList = null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,152 @@
using System;
using System.IO;
namespace NetWorkHelper
{
/// <summary>
/// 文件管理类
/// </summary>
public class SendFileManager : IDisposable
{
#region
private FileStream _fileStream;
#endregion
#region
public SendFileManager(string fileName)
{
FileName = fileName;
Create(fileName);
}
public SendFileManager(string fileName, int partSize)
{
FileName = fileName;
PartSize = partSize;
Create(fileName);
}
#endregion
#region
public long PartCount { get; set; }
public long Length { get; private set; }
public int PartSize { get; } = 1024 * 20;
public string FileName { get; }
public string Name
{
get { return new FileInfo(FileName).Name; }
}
public string MD5 { get; private set; }
public object Tag { get; set; }
internal Stream FileStream { get; private set; }
#endregion
#region
/// <summary>
/// 创建初始化文件管理类
/// </summary>
/// <param name="fileName">文件路径</param>
private void Create(string fileName)
{
_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, PartSize * 10, true);
FileStream = Stream.Synchronized(_fileStream);
Length = _fileStream.Length;
PartCount = Length / PartSize;
if (Length % PartSize != 0)
{
PartCount++;
}
MD5 = MD5Helper.CretaeMD5(_fileStream);
}
/// <summary>
/// 读取文件
/// </summary>
/// <param name="index"></param>
public void Read(int index)
{
int size = PartSize;
if (Length - PartSize * index < PartSize)
{
size = (int)(Length - PartSize * index);
}
byte[] buffer = new byte[size];
ReadFileObject obj = new ReadFileObject(index, buffer);
FileStream.Position = index * PartSize;
FileStream.BeginRead(buffer, 0, size, new AsyncCallback(EndRead), obj);
}
/// <summary>
/// 结束读取文件
/// </summary>
/// <param name="result"></param>
private void EndRead(IAsyncResult result)
{
if (FileStream == null)
{
return;
}
int length = FileStream.EndRead(result);
ReadFileObject state = (ReadFileObject)result.AsyncState;
int index = state.Index;
byte[] buffer = state.Buffer;
ReadFileBufferEventArgs e = null;
if (length < PartSize)
{
byte[] realBuffer = new byte[length];
Buffer.BlockCopy(buffer, 0, realBuffer, 0, length);
e = new ReadFileBufferEventArgs(index, realBuffer);
}
else
{
e = new ReadFileBufferEventArgs(index, buffer);
}
OnReadFileBuffer(e);
}
#endregion
#region
/// <summary>
/// 读取文件事件
/// </summary>
public event ReadFileBufferEventHandler ReadFileBuffer;
/// <summary>
/// 读取文件方法
/// </summary>
/// <param name="e"></param>
protected void OnReadFileBuffer(ReadFileBufferEventArgs e)
{
ReadFileBuffer?.Invoke(this, e);
}
#endregion
#region IDisposable
public void Dispose()
{
if (_fileStream != null)
{
FileStream.Flush();
FileStream.Close();
FileStream.Dispose();
FileStream = null;
_fileStream = null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,65 @@
using System;
namespace NetWorkHelper
{
/// <summary>
/// 消息单元类(可序列化)
/// </summary>
[Serializable]
public class MsgCell : IDataCell
{
/// <summary>
/// 消息标识
/// </summary>
public int MessageId { get; set; }
private object _data;
/// <summary>
/// 消息序列化数据
/// </summary>
public object Data
{
get { return _data; }
set { _data = value; }
}
#region
public MsgCell() { }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="messageId">消息标识</param>
/// <param name="data">序列化数据</param>
public MsgCell(
int messageId,
object data)
{
MessageId = messageId;
_data = data;
}
#endregion
/// <summary>
/// 将数据序列化成Byte[]数组
/// </summary>
/// <returns></returns>
public byte[] ToBuffer()
{
byte[] data = SerHelper.Serialize(_data);
byte[] id = BitConverter.GetBytes(MessageId);
byte[] buffer = new byte[data.Length + id.Length];
Buffer.BlockCopy(id, 0, buffer, 0, id.Length);
Buffer.BlockCopy(data, 0, buffer, id.Length, data.Length);
return buffer;
}
/// <summary>
/// 将Byte[]数组反序列化成数据结构
/// </summary>
/// <param name="buffer"></param>
public void FromBuffer(byte[] buffer)
{
MessageId = BitConverter.ToInt32(buffer, 0);
_data = SerHelper.Deserialize(buffer, 4);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
namespace NetWorkHelper
{
[Serializable]
public class MsgTypeCell
{
private MsgType _msgType;
private string _imageSuffix = "";
private byte[] _bufferBytes;
/// <summary>
/// 消息类型
/// </summary>
public MsgType Msgtype
{
get { return _msgType; }
set { _msgType = value; }
}
/// <summary>
/// 图片后缀格式
/// </summary>
public string ImageSuffix
{
get { return _imageSuffix; }
set { _imageSuffix = value; }
}
public byte[] BufferBytes
{
get { return _bufferBytes; }
set { _bufferBytes = value; }
}
public MsgTypeCell(MsgType msgType, byte[] buffer)
{
Msgtype = msgType;
BufferBytes = buffer;
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
namespace NetWorkHelper
{
[Serializable]
public class ResponeTraFransfersFile
{
private string _md5;
private int _size;
private int _index;
public ResponeTraFransfersFile() { }
public ResponeTraFransfersFile(string md5, int size, int index)
{
_md5 = md5;
_size = size;
_index = index;
}
public string MD5
{
get { return _md5; }
set { _md5 = value; }
}
public int Size
{
get { return _size; }
set { _size = value; }
}
public int Index
{
get { return _index; }
set { _index = value; }
}
}
}

View File

@@ -0,0 +1,201 @@
using System;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
namespace NetWorkHelper
{
public class UdpLibrary : IDisposable
{
#region
public UdpLibrary(int port)
{
Port = port;
}
public UdpLibrary()
{
//默认监听端口1234
Port = 1234;
}
#endregion
#region
private UdpClient _udpClient;
private bool _started;
#endregion
#region
[Description("UDP监听端口")]
[Category("UDP服务端")]
public int Port { get; set; } = 1234;
[Description("UDP客户端")]
[Category("UDP服务端")]
internal UdpClient UdpClient
{
get
{
if (_udpClient == null)
{
bool success = false;
while (!success)
{
try
{
_udpClient = new UdpClient(Port);
success = true;
}
catch (SocketException ex)
{
Port++;
if (Port > 65535)
{
success = true;
throw ex;
}
}
}
uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
_udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
}
return _udpClient;
}
}
#endregion
#region
public void Start()
{
if (!_started)
{
_started = true;
ReceiveInternal();
}
}
public void Stop()
{
try
{
_started = false;
UdpClient.Close();
_udpClient = null;
}
catch
{
}
}
public void Send(IDataCell cell, IPEndPoint remoteIP)
{
byte[] buffer = cell.ToBuffer();
SendInternal(buffer, remoteIP);
}
public void Send(byte[] buffer, IPEndPoint remoteIP)
{
SendInternal(buffer, remoteIP);
}
protected void SendInternal(byte[] buffer, IPEndPoint remoteIP)
{
if (!_started)
{
throw new ApplicationException("UDP Closed.");
}
try
{
UdpClient.BeginSend(buffer, buffer.Length, remoteIP, new AsyncCallback(SendCallback), null);
}
catch (SocketException ex)
{
throw ex;
}
}
public bool IsStarted()
{
return _started;
}
protected void ReceiveInternal()
{
if (!_started)
{
return;
}
try
{
UdpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
}
catch (SocketException ex)
{
//_started = false;
throw ex;
}
}
void SendCallback(IAsyncResult result)
{
try
{
UdpClient.EndSend(result);
}
catch (SocketException ex)
{
throw ex;
}
}
void ReceiveCallback(IAsyncResult result)
{
if (!_started)
{
return;
}
IPEndPoint remoteIP = new IPEndPoint(IPAddress.Any, 0);
byte[] buffer = null;
try
{
buffer = UdpClient.EndReceive(result, ref remoteIP);
}
catch (SocketException ex)
{
throw ex;
}
finally
{
ReceiveInternal();
}
OnReceiveData(new ReceiveDataEventArgs(buffer, remoteIP));
}
#endregion
#region IDisposable
public void Dispose()
{
_started = false;
if (_udpClient != null)
{
_udpClient.Close();
_udpClient = null;
}
}
#endregion
#region
public event ReceiveDataEventHandler ReceiveData;
[Description("UDP服务端接收数据事件")]
[Category("UDPServer事件")]
protected virtual void OnReceiveData(ReceiveDataEventArgs e)
{
ReceiveData?.Invoke(this, e);
}
#endregion
}
}