C# TCP/IP文件(图片、视频等)收发系统

功能介绍:

1. 窗口最小化到托盘及右键图标显示菜单;
2. D:\Picture\device2 D:\Picture\device1 D:\Record
路径下有数据更新以后将新增加的文件通过TCP/IP上传到云端;
3. 界面上可以显示数据收发的进度条;
注意:1. 收发用同一个客户端 2. LocalPort 收发端需要不一样.

知识点:
1. 多线程操作
2. 监控文件夹路径下文件更新
3. tcp/ip 数据收发
4. 进度条用法
5. log文件记录
6. xml文件读取等

运行结果:

C# TCP/IP文件(图片、视频等)收发系统

MainForm

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.Net;
using System.Net.Sockets;
namespace FileTransceiver
{
    public partial class MainForm : DevComponents.DotNetBar.OfficeForm
    {
        private string fileName;
        private string filePath;
        private long fileSize;
        private string remoteIP;
        private int localPort;
        private int remotePort;
        public static int pathFlag = 1;
        public static string storagePath = null;
        private string picSavePath1 = null, picSavePath2 = null, videoSavePath = null;
        public MainForm()
{
            try
            {
                this.EnableGlass = false;
                InitializeComponent();
                ReadConfigXML();

                FileRecive fr = new FileRecive(this, localPort);
                Thread fileRecive = new Thread(fr.run);         //开启数据接收线程                      
                fileRecive.Start();
                fileRecive.IsBackground = true;                //后台运行

                TestFileSystemWatcher();
            }
            catch (Exception ex)
            {
                logWrite(ex.Message, ex.StackTrace);
            }
        }
        private void ReadConfigXML()
{
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "\\config.xml");
                XmlNode settingNode = xmlDoc.DocumentElement;

                XmlElement e = settingNode.SelectSingleNode("RemoteIP") as XmlElement;
                if (e != null)
                {
                    remoteIP = e.InnerText;
                }
                else
                {
                    remoteIP = "192.168.1.119";
                }

                e = settingNode.SelectSingleNode("RemotePort") as XmlElement;
                if (e != null)
                {
                    remotePort = int.Parse(e.InnerText);
                }
                else
                {
                    remotePort = 8007;
                }

                e = settingNode.SelectSingleNode("LocalPort") as XmlElement;
                if (e != null)
                {
                    localPort = int.Parse(e.InnerText);
                }
                else
                {
                    localPort = 8007;
                }

                e = settingNode.SelectSingleNode("PicSavePath1") as XmlElement;
                if (e != null)
                {
                    picSavePath1 = e.InnerText;
                }
                else
                {
                    picSavePath1 = @"D:\Picture\device1";
                }
                e = settingNode.SelectSingleNode("PicSavePath2") as XmlElement;
                if (e != null)
                {
                    picSavePath2 = e.InnerText;
                }
                else
                {
                    picSavePath2 = @"D:\Picture\device2";
                }
                e = settingNode.SelectSingleNode("VideoSavePath") as XmlElement;
                if (e != null)
                {
                    videoSavePath = e.InnerText;
                }
                else
                {
                    videoSavePath = @"D:\Record";
                }
            }

            catch (Exception ex)
            {
                logWrite(ex.Message, ex.StackTrace);
            }
        }
        public void TestFileSystemWatcher()
{
            try
            {
                FileSystemWatcher watcher1 = new FileSystemWatcher();
                FileSystemWatcher watcher2 = new FileSystemWatcher();
                FileSystemWatcher watcher3 = new FileSystemWatcher();
                try
                {
                    watcher1.Path = @"D:\Picture\device1";
                    watcher2.Path = @"D:\Picture\device2";
                    watcher3.Path = @"D:\Record";
                }
                catch (ArgumentException e)
                {
                    Console.WriteLine(e.Message);
                    return;
                }
                //设置监视文件的哪些修改行为
                watcher1.NotifyFilter = NotifyFilters.LastAccess
                    | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                // watcher.Filter = "*.jpg";
                watcher1.Created += new FileSystemEventHandler(OnChanged);
                watcher1.EnableRaisingEvents = true;

                watcher2.NotifyFilter = NotifyFilters.LastAccess
                     | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                watcher2.Created += new FileSystemEventHandler(OnChanged);
                watcher2.EnableRaisingEvents = true;

                watcher3.NotifyFilter = NotifyFilters.LastAccess
                    | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                watcher3.IncludeSubdirectories = true;
                watcher3.Created += new FileSystemEventHandler(OnChanged);
                watcher3.EnableRaisingEvents = true;
            }
            catch (Exception ex)
            {
                logWrite(ex.Message, ex.StackTrace);
            }
        }

        public void OnChanged(object source, FileSystemEventArgs e)
{
            Task.Run(() =>
            {
                try
                {

                //string ip = "101.91.224.228";
                //string ip = "192.168.0.194";
                //string port = "8008";
                if (Directory.Exists(e.FullPath))
                {
                    return;
                }
                    string[] videoPath;
                    while (IsFileInUse(e.FullPath)) ;
                    FileInfo f = new FileInfo(e.FullPath);
                    this.fileSize = f.Length;
                    //this.filePath = f.DirectoryName;
                    this.filePath = f.FullName;
                    this.fileName = f.Name;
                    if (fileName.Length == 0)
                    {
                        Tip("请选择文件");
                        return;
                    }
                    if (!File.Exists(f.FullName))
                    {
                        Tip("不存在" + f.FullName);
                        return;
                    }

                
                    videoPath = f.DirectoryName.Split('\\');
                    switch (f.DirectoryName)
                    {
                        case @"D:\Picture\device1": storagePath = picSavePath1; break;
                        case @"D:\Picture\device2": storagePath = picSavePath2; break;
                        //default: storagePath = videoSavePath + "\\"+ fileName; break;
                        default:
                            if (videoPath.Length >= 2)
                                storagePath = videoSavePath + "\\" + videoPath[2]; break;
                    }
                    //Thread.Sleep(1000);
                  
                    while (IsFileInUse(f.FullName)) ;
                    logWrite(e.FullPath, fileSize.ToString());

                    var c = new FileSend(this, new string[] { remoteIP, remotePort.ToString(), fileName, filePath, fileSize.ToString(), storagePath });
                    //new Thread(c.Send).Start();
                    Thread fileSendThread = new Thread(c.Send);
                    fileSendThread.Start();
                    fileSendThread.IsBackground = true;

                }
                catch (Exception ex)
                {
                    logWrite(ex.Message, ex.StackTrace);
                }
            });
        }
        //public void OnChanged_v1(object source, FileSystemEventArgs e)
        //{
        //    try
        //    {
        //        FileInfo f = new FileInfo(e.FullPath);
        //        FileSystemWatcher watcher1 = new FileSystemWatcher();
        //        try
        //        {
        //            watcher1.Path = f.FullName;
        //        }
        //        catch (ArgumentException ex)
        //        {
        //            Console.WriteLine(ex.Message);
        //            return;
        //        }
        //        //设置监视文件的哪些修改行为
        //        watcher1.NotifyFilter = NotifyFilters.LastAccess
        //            | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        //        watcher1.Created += new FileSystemEventHandler(OnChanged);
        //        watcher1.EnableRaisingEvents = true;
        //    }
        //    catch (Exception ex)
        //    {
        //        logWrite(ex.Message, ex.StackTrace);
        //    }


        //}
            public static bool IsFileInUse(string fileName)
{
            bool inUse = true;

            FileStream fs = null;
            try
            {

                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,

                FileShare.None);

                inUse = false;
            }
            catch
            {
            }
            finally
            {
                if (fs != null)

                    fs.Close();
            }
            return inUse;//true表示正在使用,false没有使用  
        }
        public void Tip(string msg)
{
            MessageBox.Show(msg, "温馨提示");
        }
        public void SetState(string state)
{
            label1.Text = state;
        }
        public void UpDateProgress(int value)
{

            this.progressBarX1.Value = value;
            this.label2.Text = value + "%";
            System.Windows.Forms.Application.DoEvents();
        }

        #region //WinForm 之 窗口最小化到托盘及右键图标显示菜单 
        //https://www.cnblogs.com/xinaixia/p/6216670.html
        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
            if (e.Button == MouseButtons.Left)//判断鼠标的按键            
            {
                //点击时判断form是否显示,显示就隐藏,隐藏就显示               
                if (this.WindowState == FormWindowState.Normal)
                {
                    this.WindowState = FormWindowState.Minimized;
                    this.Hide();
                }
                else if (this.WindowState == FormWindowState.Minimized)
                {
                    this.Show();
                    this.WindowState = FormWindowState.Normal;
                    this.Activate();
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                //右键退出事件                
                if (MessageBox.Show("是否需要关闭程序?", "提示:", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK)//出错提示                
                {
                    //关闭窗口                    
                    DialogResult = DialogResult.No;
                    Dispose();
                    Close();
                }
            }

        }
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
            if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                // 关闭所有的线程
                this.Dispose();
                this.Close();
            }
            else
            {
                e.Cancel = true;
            }
        }
        private void MainForm_SizeChanged(object sender, EventArgs e)
{
            //判断是否选择的是最小化按钮
            if (WindowState == FormWindowState.Minimized)
            {
                //隐藏任务栏区图标
                this.ShowInTaskbar = false;
                //图标显示在托盘区
                notifyIcon1.Visible = true;
            }
        }
        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否确认退出程序?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                // 关闭所有的线程
                this.Dispose();
                this.Close();
            }
        }
        private void 显示ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Normal;
        }
        #endregion
        /// <summary>
        /// 退出程序
        /// </summary>
        public void Exit()
{

            Application.Exit();
        }
        public void logWrite(string Message,string StackTrace)
{
            if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\log.txt"))
                File.Create(AppDomain.CurrentDomain.BaseDirectory + "\\log.txt").Close();
            string fileName = AppDomain.CurrentDomain.BaseDirectory + "\\log.txt";
            string content = DateTime.Now.ToLocalTime() + Message + "\n" + StackTrace + "\r\n";
            StreamWriter sw = new StreamWriter(fileName, true);
            sw.Write(content);
            sw.Close(); sw.Dispose();
        }
    }
}

WinForm 之 窗口最小化到托盘及右键图标显示菜单https://www.cnblogs.com/xinaixia/p/6216670.html

类:IpUtil.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace FileTransceiver
{
    class IpUtil
    {
        /// <summary>
        /// 获取本地ip地址
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIp()
        {
            string hostname = Dns.GetHostName();
            IPHostEntry localhost = Dns.GetHostByName(hostname);
            IPAddress localaddr = localhost.AddressList[0];
            return localaddr.ToString();
        }
        /// <summary>
        /// 产生随机端口
        /// </summary>
        /// <returns></returns>
        public static int GetRandomPort()
        {

            return new Random().Next(1000) + 5000;
        }
    }
}

类FileSend.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace FileTransceiver
{
    class FileSend
    {
        private TcpClient client;
        private NetworkStream stream;
        private string[] param;
        private MainForm fm;
        public FileSend(MainForm fm, params string[] param)
        {
            this.param = param;
            this.fm = fm;

        }
        public void Send()
        {

            try
            {
                //连接接收端
                
                this.client = new TcpClient(param[0], int.Parse(param[1]));
                //string msg = param[2] + "|" + param[3] + "|" + param[4];
                string msg = param[2] + "|" + param[4]+ "|" + param[5];
                byte[] m = Encoding.UTF8.GetBytes(msg);

                //Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(param[0]), int.Parse(param[1]));
                //IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(param[0]), 8008);
                //socket.Connect(ipep);

                //while (true)
                {
                    
                    this.stream = this.client.GetStream();
                    this.stream.Write(m, 0, m.Length);
                    this.stream.Flush();
                    byte[] data = new byte[1024];
                    int len = this.stream.Read(data, 0, data.Length);
                    msg = Encoding.UTF8.GetString(data, 0, len);
                    //对方要接收我发送的文件
                    if (msg.Equals("1"))
                    {
                        fm.SetState("正在发送:");
                        FileStream os = new FileStream(param[3], FileMode.OpenOrCreate);

                        data = new byte[1024];
                        //记录当前发送进度
                        long currentprogress = 0;
                        len = 0;
                        while ((len = os.Read(data, 0, data.Length)) > 0)
                        {
                            currentprogress += len;
                            //更新进度条
                            if (long.Parse(param[4]) != 0)
                                fm.UpDateProgress((int)(currentprogress * 100 / long.Parse(param[4])));
                            this.stream.Write(data, 0, len);

                        }
                        os.Flush();
                        this.stream.Flush();
                        os.Close();
                        this.stream.Close();


                        //fm.Tip("发送成功!");
                        //fm.Exit();
                        //socket.Close();

                    }
                }
            }
            catch (Exception e)
            {
                fm.Tip(e.Message);          
                fm.logWrite(e.Message, e.StackTrace);
            
        }
        }
    }
}

FileRecive.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FileTransceiver
{
    class FileRecive
    {
        private TcpListener server;
        private MainForm fm;
        private NetworkStream stream;
        public FileRecive(MainForm fm,int port)
        {
            this.fm = fm;
            try
            {
                //this.server = new TcpListener(IPAddress.Parse(IpUtil.GetLocalIp()), IpUtil.GetRandomPort());
                //MessageBox.Show(IPAddress.Any.ToString() +" " + port.ToString());
                this.server = new TcpListener(IPAddress.Any, port);
                server.Start();
            }
            catch (Exception e)
            {
                fm.Tip(e.Message);

            }
        }
        public void run()
        {
            while (true)
            {
                try
                {
                    TcpClient client = server.AcceptTcpClient();
                    this.stream = client.GetStream();
                    byte[] msgs = new byte[1024];
                    int len = this.stream.Read(msgs, 0, msgs.Length);
                    string msg = Encoding.UTF8.GetString(msgs, 0, len);
                    string[] tip = msg.Split('|');
                    //if (DialogResult.Yes == MessageBox.Show(IpUtil.GetLocalIp() + "给您发了一个文件:" + tip[0] + "大小为:" + (long.Parse(tip[1]) / 1024) + "kb ,确定要接收吗?", "接收提醒", MessageBoxButtons.YesNo))
                    {
                        //将接收信息反馈给发送方
                        msg = "1";
                        msgs = Encoding.UTF8.GetBytes(msg);
                        this.stream.Write(msgs, 0, msgs.Length);
                        this.stream.Flush();
                        fm.SetState("正在接收:");
                        //开始接收文件
                        string path = tip[2] +"\\"+ tip[0];//接收文件的存储路径
                        if (!Directory.Exists(tip[2]))
                            Directory.CreateDirectory(tip[2]);
                        FileStream os = new FileStream(path, FileMode.OpenOrCreate);
                        byte[] data = new byte[1024];
                        long currentprogress = 0;
                        int length = 0;
                        while ((length = this.stream.Read(data, 0, data.Length)) > 0)
                        {
                            currentprogress += length;
                            //更新进度条
                            if(long.Parse(tip[1])!=0)
                            fm.UpDateProgress((int)(currentprogress * 100 / long.Parse(tip[1])));
                            os.Write(data, 0, length);
                        }
                        os.Flush();
                        this.stream.Flush();
                        os.Close();
                        this.stream.Close();
                        //fm.Tip("成功接收文件并存入了" + path + "中!");
                        //fm.Exit();
                    }
                }
                catch (Exception e)
                {
                    fm.Tip(e.Message);
                    fm.logWrite(e.Message, e.StackTrace);
                }
            }
        }
    }
}

bin文件:

C# TCP/IP文件(图片、视频等)收发系统

<?xml version="1.0" encoding="utf-8"?>
<Setting>
  <RemoteIP>192.168.0.194</RemoteIP>
  <RemotePort>8008</RemotePort>
  <LocalPort>8007</LocalPort>
  <PicSavePath1>C:\Picture\device1</PicSavePath1>
  <PicSavePath2>C:\Picture\device2</PicSavePath2>
  <VideoSavePath>C:\Record</VideoSavePath>
</Setting>