C# UdpClient Udp收发

UdpClient

IPAddress.Any == ip(0.0.0.0)

        发送方: 
            需要知道 接收方的ip 和 接收方开放的端口(port) ip =接收方的ip ,port = 接收方开放的端口
        接收方:
            不需要知道 发送方的ip 和 发送方的开放的端口,
            只需要 监听一个 已经开放的端口  ,  ip =0.0.0.0 ,port = 接收方开放的端口

通信协议代表ip是否固定访问限制是否可以先手访问服务器是否可以先手访问普通宽带用户
Udp服务器公网固定Ip门是开着的
普通宽带用户内网随机ip门是锁着的


普通宽带用户 和 服务器
    如果  接收方 没有固定IP ,ip是宽带临时分配的话属于内网,是没有办法接收到消息的.因为net屏蔽了.
    如果  接收方 是服务器固定IP ,可以接收到消息的
    发送方 无论是 普通宽带用户 还是 服务器都可以 正常发送

也就是说 服务器 不可以先手 访问 普通宽带用户 , 相当于 普通宽带用户 的门是有锁(NET)的 ,服务器进不去

只有 普通宽带用户  先手访问服务器 ,给服务器钥匙,它才能用钥匙打开门,第二手才能和普通宽带用户通信,

公网固定Ip 的门是开着的, 别的ip可以随时访问他

内网随机ip 普通宽带用户,的门是锁着的, 只有先给公网固定Ip钥匙,公网固定Ip才能开门

Send

using System;
using System.Net;
using System.Net.Sockets;

class UdpSend
{
    public void Send(string Msg, IPEndPoint remotePoint)
    {
        try
        {
            //using (var udpSendClient = new UdpClient(54757)) //这里 ip 是你公网的ip  ,端口是  54757 ,这里就是固定端口发
            using (var udpSendClient = new UdpClient()) //这里 ip 是你公网的ip  ,端口是 以電腦會依流水號的方式分配Port,每次加1
            {
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Msg);
                udpSendClient.Send(buffer, buffer.Length, remotePoint);
                // udpSendClient.Close(); //使用了using 就不需要自己释放了
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

Revice 

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

class UdpRev
{
    bool _IsStartUdpRecive = false;
    public bool IsStartUdpRecive // ==false 关闭 udp 的监听 ,只用来关闭,不能开启
    {
        get { return _IsStartUdpRecive; }
        set
        {
            _IsStartUdpRecive = value;
            if (value == false)
            {
                thread?.Abort(); //强制关闭当前线程
                udpRecvClient?.Close();
            }
        }
    }
    public Action<string> Rev_msg; //收到消息事件
    private UdpClient udpRecvClient;
    private Thread thread;  //后台监听
    public void Listen(int port_)
    {
        var iPEndPoint = new IPEndPoint(IPAddress.Any, port_);
        try
        {
            udpRecvClient = new UdpClient(iPEndPoint);
            IsStartUdpRecive = true;
            thread = new Thread(() => //开启一个线程  后台监听端口
            {
                while (IsStartUdpRecive)
                {
                    Console.WriteLine("IsStartUdpRecive" + IsStartUdpRecive);
                    byte[] recBuffer = udpRecvClient.Receive(ref iPEndPoint); //Receive方法 阻塞直到有消息返回
                        if (recBuffer != null)
                    {
                        string receive = System.Text.Encoding.UTF8.GetString(recBuffer);
                        Console.WriteLine("[" + iPEndPoint.ToString() + "]:" + receive);
                        Rev_msg("[" + iPEndPoint.ToString() + "]:" + receive + "\r\n");
                    }
                }

                if (IsStartUdpRecive == false)
                {
                    udpRecvClient?.Close();
                    thread?.Abort(); //强制关闭当前线程
                    }
            });
            thread.Start();
        }
        catch (Exception ex)
        {

            IsStartUdpRecive = false;
            udpRecvClient?.Close();
            thread?.Abort(); //强制关闭当前线程
            Console.WriteLine("Error:" + ex.Message);
            throw ex;
        }
    }
}

Use 

using System;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Forms;

namespace Udp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            button4.Text = "Open Port And Listen";
        }

        private void button2_Click(object sender, EventArgs e) //发送消息按钮
        {
            IPAddress ip = IPAddress.Parse(textBox1.Text);
            int port = int.Parse(textBox2.Text);
            IPEndPoint ipEndPoint = new IPEndPoint(ip,port );

            //检查端口是否被占用了
            if (LocalPortInUse(ipEndPoint.Port, false))
            {
                MessageBox.Show("Local Port:[" + ipEndPoint.Port + "] already be use ,No Method Open and Listen");
                return;
            }

            var send = new UdpSend();
            send.Send(textBox4.Text, ipEndPoint);
        }

        private UdpRev curr;
        private bool isListen = false;
        private void button4_Click(object sender, EventArgs e) //监听按钮
        {

            if (isListen)
            {
                if (curr != null)
                {
                    curr.IsStartUdpRecive = false;
                }
            }
            else
            {

                int port = int.Parse(textBox6.Text);

                //检查端口是否被占用了
                if (LocalPortInUse(port, false))
                {
                    MessageBox.Show("Local Port:[" + port + "] already be use ,No Method Open and Listen");
                    return;
                }
                var rev = curr = new UdpRev();
                if (rev.Rev_msg == null)
                {
                    rev.Rev_msg += x => { textBox8.AppendText(x); };
                }
                rev.Listen(port);
            }

            isListen = !isListen;
            if (isListen)
            {
                button4.Text = "Stop Port And Listen";
            }
            else
            {
                button4.Text = "Open Port And Listen";
            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (curr!=null)
            {
                curr.IsStartUdpRecive = false;
            }
            Environment.Exit(0);

        }

        /// <summary>
        /// 检测自己计算机的端口是否被占用,==ture表示被占用.偶尔特定状态时,检测不准确,就需要更换端口
        /// </summary>
        /// <param name="port"></param>
        /// <param name="isTcp"></param>
        /// <returns></returns>
        public static bool LocalPortInUse(int port, bool isTcp)
        {
            bool inUse = false;
            try
            {
                IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
                if (isTcp)
                {
                    IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
                    for (int i = 0; i < ipEndPoints.Length; i++)
                    {
                        if (ipEndPoints[i].Port == port)
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    IPEndPoint[] ipEndPoints_udp = ipProperties.GetActiveUdpListeners();
                    for (int i = 0; i < ipEndPoints_udp.Length; i++)
                    {
                        if (ipEndPoints_udp[i].Port == port)
                        {
                            return true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            return inUse;
        }
        
    }
}

exe 程序在 qq群文件夹里 431859012

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值