C#winform客户端Socket文件传输(多对1)

C#winform客户端Socket文件传输(多对1)

服务端在上一篇文章

客户端

在这里插入图片描述

代码


        Thread threadClient = null; // 创建用于接收服务端消息的 线程;

        Client client = new Client();

        public static TextBox textBox;

        public Form1()
        {
            InitializeComponent();

            textBox = txtSelectFile;

            TextBox.CheckForIllegalCrossThreadCalls = false;
          
        }
        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = "D:\\";
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtSelectFile.Text = ofd.FileName;
            }

        }

        private void btnSendFile_Click(object sender, EventArgs e)
        {
            client.FS();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("是否退出?选否,最小化到托盘", "操作提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                this.Dispose();
            }
            else if (result == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
            else
            {
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
                this.Visible = false;
                //this.ShowInTaskbar = false;
            }
        }

        private void txtSelectFile_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode == Keys.Q) && e.Control)
            {

                if (this.Visible == true)
                    this.Visible = false;
                else
                    this.Visible = true;
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {

            System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
            t.Interval = 3000;//设置执行间隔单位ms毫秒
            t.Tick += new EventHandler(client.Lock);//Lock是要执行的函数
            t.Start();//开始计时,开始循环

            threadClient = new Thread(client.link);  //自动重连线程

            threadClient.IsBackground = true;

            threadClient.Start();
        }
        /// <summary>
        /// 开机自启
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (cb_zddl.Checked) //设置开机自启动             
            {
                MessageBox.Show("设置开机自启动,需要修改注册表", "提示");
                string path = Application.ExecutablePath;
                RegistryKey rk = Registry.LocalMachine;
                RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                rk2.SetValue("frmClient", path);
                rk2.Close();
                rk.Close();
            }
            else //取消开机自启动              
            {
                MessageBox.Show("取消开机自启动,需要修改注册表", "提示");
                string path = Application.ExecutablePath;
                RegistryKey rk = Registry.LocalMachine;
                RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                rk2.DeleteValue("frmClient", false);
                rk2.Close();
                rk.Close();
            }
        }


Client类

    class Class1
    {
        public static Socket sockClient = null;

        bool Reconnect = false;

        Thread threadClient = null; // 创建用于接收服务端消息的 线程;


        private string GetIpAddress()
        {
            string hostName = Dns.GetHostName();   //获取本机名
            IPHostEntry localhost = Dns.GetHostByName(hostName);    //方法已过期,可以获取IPv4的地址
            //IPHostEntry localhost = Dns.GetHostEntry(hostName);   //获取IPv6地址
            IPAddress localaddr = localhost.AddressList[0];
            return localaddr.ToString();
        }
        /// <summary>
        /// 连接服务器
        /// </summary>
        public void link()
        {
            string hostName = Dns.GetHostName();   //获取本机名
            try
            {
                IPAddress ip = IPAddress.Parse(GetIpAddress());
                IPEndPoint endPoint = new IPEndPoint(ip, 9000);

                sockClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //ShowMsg("与服务器连接中……");

                while (true) //不断尝试连接
                {
                    try
                    {

                        sockClient.Connect(endPoint);   //尝试连接

                        string hName = Dns.GetHostName();   //获取本机名

                        string strMsg = hName;

                        byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);

                        byte[] arrSendMsg = new byte[arrMsg.Length + 1];

                        if (!Reconnect)
                        {
                            arrSendMsg[0] = 2; // 用来表示发送的是消息数据

                            Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);

                            sockClient.Send(arrSendMsg); // 发送消息;

                            threadClient = new Thread(RecMsg);  //连接成功后开启新的线程开始监听服务端是否发生消息

                            threadClient.IsBackground = true;

                            threadClient.Start();

                            return;     //连接成功后跳出死循环
                        }
                        else
                        {
                            arrSendMsg[0] = 6; // 用来表示发送的是消息数据

                            Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);

                            sockClient.Send(arrSendMsg); // 发送消息;

                            threadClient = new Thread(RecMsg);  //连接成功后开启新的线程开始监听服务端是否发生消息

                            threadClient.IsBackground = true;

                            threadClient.Start();

                            Reconnect = false;

                            return;     //连接成功后跳出死循环
                        }

                    }
                    catch (SocketException)
                    {
                        //MessageBox.Show(se.Message);
                        //return;
                        //this.Close();
                    }
                }
            }
            catch (Exception)
            {
                //MessageBox.Show("客户端配置文件不存在请联系管理员" + e.Message);
            }

        }


        void RecMsg()
        {
            string Fn = "";
            while (true)
            {
                // 定义一个2M的缓存区;
                byte[] arrMsgRec = new byte[1024 * 1024 * 100];
                // 将接受到的数据存入到输入  arrMsgRec中;
                int length = -1;
                try
                {
                    length = sockClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
                }
                catch (SocketException)
                {
                    Reconnect = true;

                    threadClient = new Thread(link);  //自动重连线程

                    threadClient.IsBackground = true;

                    threadClient.Start();

                }
                catch (Exception)
                {
                    Reconnect = true;

                    threadClient = new Thread(link);  //自动重连线程

                    threadClient.IsBackground = true;

                    threadClient.Start();

                }
                if (arrMsgRec[0] == 0) // 表示接收到的是消息数据;
                {
                    try
                    {
                        string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);// 将接受到的字节数据转化成字符串;
                        Fn = strMsg;
                        //ShowMsg(strMsg);
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("与服务器断开连接" + e);
                    }

                }
                if (arrMsgRec[0] == 1) // 表示接收到的是文件数据;
                {

                    try
                    {


                        string path = System.Windows.Forms.Application.StartupPath;

                        //判断该路径下文件夹是否存在,不存在的情况下新建文件夹

                        if (!Directory.Exists(path))
                        {

                            Directory.CreateDirectory(path);

                        }
                        string fileSavePath = path + Fn;// 获得文件保存的路径;
                        // 创建文件流,然后根据路径创建文件;
                        using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
                        {
                            fs.Write(arrMsgRec, 1, length - 1);
                        }
                        //System.Diagnostics.Process.Start(fileSavePath);
                    }
                    catch (Exception aaa)
                    {
                        MessageBox.Show(aaa.Message);
                    }
                }


            }
        }


        public void FS()
        {
            if (string.IsNullOrEmpty(Form1.textBox.Text))
            {
                MessageBox.Show("请选择要发送的文件!!!");
            }
            else
            {
                // 用文件流打开用户要发送的文件;
                using (FileStream fs = new FileStream(Form1.textBox.Text, FileMode.Open))
                {
                    if (fs.Length > 1024 * 1024 * 100)
                    {
                        MessageBox.Show("文件大于100M,不能上传");
                    }
                    else
                    {
                        //在发送文件以前先给好友发送这个文件的名字+扩展名,方便后面的保存操作;
                        string fileName = System.IO.Path.GetFileName(Form1.textBox.Text);
                        string fileExtension = System.IO.Path.GetExtension(Form1.textBox.Text);
                        string strMsg = fileName;
                        byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
                        byte[] arrSendMsg = new byte[arrMsg.Length + 1];
                        arrSendMsg[0] = 0; // 用来表示发送的是消息数据
                        Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
                        sockClient.Send(arrSendMsg); // 发送消息;

                        byte[] arrFile = new byte[1024 * 1024 * 100];
                        int length = fs.Read(arrFile, 0, arrFile.Length);  // 将文件中的数据读到arrFile数组中;
                        byte[] arrFileSend = new byte[length + 1];
                        arrFileSend[0] = 1; // 用来表示发送的是文件数据;
                        Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
                        // 还有一个 CopyTo的方法,但是在这里不适合; 当然还可以用for循环自己转化;
                        sockClient.Send(arrFileSend);// 发送数据到服务端;
                        Form1.textBox.Clear();
                    }

                }
            }
        }
    }

客户端搭建完成(服务端与客户端必须在同一网段才可通讯,安装服务端的电脑IP为广域网唯一IP也可通讯)

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET C#是一种面向对象的编程语言,它是微软公司推出的一种多平台开发框架。基于.NET C#的开发平台可以支持Windows、Linux和macOS系统,能够开发桌面应用程序、web应用程序和移动应用程序等。 .NET C#具有很多优点。首先,它具有强大的跨平台能力,可以在不同的操作系统上运行,大大提升了开发的灵活性和效率。其次,C#语言本身具有简单易学的特点,语法规则清晰,对于初学者来说比较容易上手。同时,它也拥有许多强大的库和工具,可以大大减少开发的复杂性。此外,C#还支持其他语言相关的功能,如异步编程、LINQ等,使开发更加简洁高效。 基于.NET C#的开发框架也是非常强大的。它提供了丰富的库和API,可以快速开发出高质量、可扩展的应用程序。对于数据库操作、网络通信、图形界面开发等常用功能,都有相应的库和工具来支持。同时,它还提供了一套灵活的开发模型和丰富的设计模式,可以满足不同项目的需求。 .NET C#还有一个优点是它具有良好的安全性和稳定性。在开发过程中,C#会自动进行内存管理,减少内存泄漏和垃圾回收问题。而且,C#还提供了一些强大的安全特性,如型安全、代码访问安全等,可以保证应用程序的安全性。 总之,基于.NET C#的开发平台是一种强大、灵活和高效的工具,可以帮助开发人员快速开发出高质量的应用程序。无论是开发桌面应用程序还是web应用程序,都可以选择.NET C#作为开发语言,来实现各种需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值