基于Socket实现多线程之间通讯

程序运行效果展示:

解决程序关闭后台资源未释放问题

protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
            //解决程序关闭后台资源未释放问题
            System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

 具体实现代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace UDPSendRecive
{
    public partial class SendRecive : Form
    {
        // 定义委托类型
        delegate void SetTextCallback(String str);

        static Socket client;
        Thread t1;
        Thread t2;
        bool threadFlag = false;
        bool sendFlag = false;
        bool reciveFlag = false;
        public SendRecive()
        {
            InitializeComponent();
        }

        
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (!threadFlag)
            {
                threadFlag = true;
                lbStatus.Text = "通讯中...";

                client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                try
                {
                    if (!client.IsBound)
                    {
                        //绑定IP  端口
                        client.Bind(new IPEndPoint(IPAddress.Parse(tbIPAddress.Text.ToString()), Convert.ToInt32(tbPort.Text.ToString())));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("2" + ex.Message);
                }
                t2 = new Thread(ReciveMsg);
                if (!t2.IsAlive)
                {
                    reciveFlag = true;
                    t2.Start();
                    lbReciveState.Text = "线程二已开启";
                }
            }
        }
        private void btnStop_Click(object sender, EventArgs e)
        {

            if (reciveFlag)
            {
                t1.Abort();
                reciveFlag = false;
                lbSendState.Text = "线程一已关闭";
            }
            if (threadFlag)
            {
                t2.Abort();
                client.Close();
                threadFlag = false;
                lbReciveState.Text = "线程二已关闭";
            }
            lbStatus.Text = "通讯停止!";
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            t1 = new Thread(SendMsg);
            if (!t1.IsAlive)
            {
                t1.Start();
                lbSendState.Text = "线程一已开启";
            }
            sendFlag = true;
        }

        private void SendMsg()
        {
            EndPoint epoint = new IPEndPoint(IPAddress.Parse(tbIPAddress.Text.ToString()), Convert.ToInt32(tbPort.Text.ToString()));
            try
            {
                while (threadFlag && sendFlag)
                {
                    string msg = tbSendMsg.Text.ToString();
                    client.SendTo(Encoding.UTF8.GetBytes(msg), epoint);
                    sendFlag = false;//发送完消息,中断循环
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("1" + e.Message);
            }
        }

        private void ReciveMsg()
        {
            try
            {
                while (reciveFlag)
                {
                    EndPoint point = new IPEndPoint(IPAddress.Any, 0);//用来保存发送方的ip和端口号
                    byte[] buffer = new byte[1024];
                    int length = client.ReceiveFrom(buffer, ref point);//接收数据报
                    string message = Encoding.UTF8.GetString(buffer, 0, length);
                    setText(message);
                }
            }
            catch (Exception e)
            {
                //MessageBox.Show("3" + e.Message);
            }
        }

        // 使用控件的Invoke/BeginInvoke方法,将委托转到UI线程上调用
        // 本质上还是把线程中要提交的消息,通过控制句柄调用委托交到UI线程中处理
        public void setText(String str)
        {
            if (tbReciveMsg.InvokeRequired)
            {
                // 解决窗体关闭时出现“访问已释放句柄”异常
                while (tbReciveMsg.IsHandleCreated == false)
                {
                    if (tbReciveMsg.Disposing || tbReciveMsg.IsDisposed) return;
                }

                SetTextCallback d = new SetTextCallback(setText);
                tbReciveMsg.Invoke(d, new object[] { str });

            }
            else
            {
                if (tbReciveMsg.Text == "")
                {
                    tbReciveMsg.Text = str;
                }
                else
                {
                    tbReciveMsg.Text += "," + str;
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值