• C#UDP同步实例


    差不多有一个礼拜总算有点进步。

    代码很简单,只是为了实现功能。

    网络上的资源是很多,除了不能用的,就是抄来抄去,是在乏味浪费时间。

    说一下代码背景:实现的功能是发送端发送消息,接收端接收后立即响应,发送端接受响应的消息。类似心跳数据,超时后更换自己IP。

            就是一个备份机上运行的程序,向主机发送心跳数据,如果主机挂了(接受超时),备份机更换自己IP为主机IP。

    接收端

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    namespace HostBackupReciever
    {
    public class UdpReceiver
    {
    private UdpClient _udpClient;
    private Thread _recvThread;

    public UdpReceiver()
    {
    _udpClient = new UdpClient(11000);
    }

    public void StartReceive()
    {
    _recvThread = new Thread(new ThreadStart(Receive));
    _recvThread.Start();
    }

    private void Receive() {
    int count = 0;
    while (true)
    {
    try
    {
    byte[] recvBytes = new byte[1024];
    IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);
    recvBytes = _udpClient.Receive(ref point);
    Console.WriteLine("I'm Receiver:" + DateTime.Now.ToString() + "--->接收消息:" + Encoding.Default.GetString(recvBytes));
    if (recvBytes != null)
    {
    string sts = "北平地铁又瘫痪了";
    byte[] bs = Encoding.Default.GetBytes(sts);
    if (count == 10) {
    Thread.Sleep(11000);
    }
    _udpClient.Send(bs, bs.Length, point);
    Console.WriteLine("I'm Receiver:我已发送消息--" + sts + "" +count + "");
    }
    count++;

    }
    catch (Exception ex) {
    Console.WriteLine(ex.Message);
    }
    }
    }
    }
    }

    启动接收端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace HostBackupReciever
    {
    class RecerverService
    {
    public static void main(string[] args) {
    Console.WriteLine("receiver start");
    UdpReceiver receiver = new UdpReceiver();
    receiver.StartReceive();
    }
    }
    }

    发送端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;

    namespace ChooseIPDemo
    {
    public class UdpChecker
    {

    private UdpClient _udpClient;
    private Thread _sendThread;
    private string _sendIp;//绑定的发送ip
    private bool status = true; //标记线程状态,中止线程运行
    public event EventHandler<CheckerEventArgs> HostDisconnectedHandler;//保存地址信息
    //
    private void OnHostDisconnected(string address)
    {
    try
    {
    Console.WriteLine("开始停止线程");
    }
    catch (Exception e)
    {
    Console.WriteLine("exception" + e.Message);
    }
    if(HostDisconnectedHandler!=null)
    HostDisconnectedHandler(this, new CheckerEventArgs() { HostAddress = address });//直接给HostAddress赋值
    Console.WriteLine("已将address设置完毕");
    }
    //
    public UdpChecker(string _sendIp)
    {
    _udpClient = new UdpClient(12000);
    this._sendIp = _sendIp;
    }
    //
    public void StartCheck()
    {
    _sendThread = new Thread(new ThreadStart(Check));
    _sendThread.Start();
    }
    private void Check()
    {
    int count = 0;
    while (status) {
    try
    {
    string msg = "告诉我今天的新闻第" + count + "";
    IPEndPoint point = new IPEndPoint(IPAddress.Parse(_sendIp), 11000);//
    byte[] msgBytes = Encoding.Default.GetBytes(msg);
    _udpClient.Send(msgBytes, msgBytes.Length, point);
    DateTime sendTime = DateTime.Now;
    DateTime recvTime = DateTime.Now;
    Console.WriteLine("I'm Sender:已经发送:" + msg);
    count++;
    byte[] recBytes = _udpClient.Receive(ref point);
    if (recBytes != null)
    {
    Console.WriteLine("I'm Sender:接受的来自receiver的消息:" + Encoding.Default.GetString(recBytes));
    recvTime = DateTime.Now;
    _sendIp = point.Address.ToString();
    }
    if ((recvTime - sendTime).TotalSeconds > 5)
    {
    Console.WriteLine("收取超时");
    status = false;
    OnHostDisconnected(_sendIp);
    }
    }
    catch (SocketException ex)
    {
    Console.WriteLine(ex.ToString());
    }
    finally
    {
    Thread.Sleep(2000);
    }
    }
    }
    }
    /**/
    public class CheckerEventArgs:EventArgs
    {
    private string hostAddress;
    public string HostAddress
    {
    get
    {
    return hostAddress;
    }
    set
    {
    hostAddress = value;
    }
    }
    }
    }

    启动发送端:(需要添加一个DLL:System.Management.DLL,不添加也可以,将ChangIP方法去掉,默认注释掉了,)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Management;
    namespace ChooseIPDemo
    {
    class HotBakupService
    {
    public static void Main() {
    UdpChecker checker = new UdpChecker("127.0.0.1");//目标主机IP,也是超时后备用机要切换的IP
    checker.StartCheck();
    checker.HostDisconnectedHandler += new EventHandler<CheckerEventArgs>(checker_HostDisconnectedHandler);//注册事件
    Console.ReadKey();
    }
    static void checker_HostDisconnectedHandler(object sender, CheckerEventArgs e)
    {
    Console.WriteLine("事件响应成功");
    Console.WriteLine(e.HostAddress);
    //ChangeIP(e.HostAddress);
    Console.ReadKey();
    }
           /* 
        static void ChangeIP(string ipaddress)
    {
    ManagementBaseObject inPar = null;
    ManagementBaseObject outPar = null;
    ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
    ManagementObjectCollection moc = mc.GetInstances();
    foreach (ManagementObject mo in moc)
    {
    if (!(bool)mo["IPEnabled"])
    continue;
    //设置ip地址和子网掩码
    inPar = mo.GetMethodParameters("EnableStatic");
    inPar["IPAddress"] = new string[] { "192.168.1.252" };// { "192.168.1.252" ,"192.168.1.254"}1.备用 2.IP,
    inPar["SubnetMask"] = new string[] { "255.255.255.0" };
    outPar = mo.InvokeMethod("EnableStatic", inPar, null);
    //设置网关地址
    inPar = mo.GetMethodParameters("SetGateways");
    inPar["DefaultIPGateway"] = new string[] { "192.168.1.1" }; // 1.网关;2.备用网关
    outPar = mo.InvokeMethod("SetGateways", inPar, null);
    //设置DNS
    inPar = mo.GetMethodParameters("SetDNSServerSearchOrder");
    inPar["DNSServerSearchOrder"] = new string[] { "202.97.224.69", "202.97.224.68" }; // 1.DNS 2.备用DNS
    outPar = mo.InvokeMethod("SetDNSServerSearchOrder", inPar, null);
    break;
    }
    }*/
    }

    }


    结果图:第十次的时候设置较长间隔,接受时间超时,成功。

  • 相关阅读:
    ajax原理及封装
    javascript 递归调用
    CSS的五种定位方式
    vue中iframe结合window.postMessage实现父子页面间的通信
    vue将文件流的形式的图形验证码转换成图片
    路由跳转打开新窗口,传递的参数不显示在地址栏
    js判断是否是ie浏览器、360浏览器兼容模式、QQ浏览器兼容模式、搜狗浏览器兼容模式,弹出提示使用别的浏览器打开
    vue项目中使用iframe嵌入静态页面,动态获取静态页面的高度赋值给iframe的高度
    vue项目中使用iview组件中的table插件实现表头文字居中,内容文字居左
    vue前端开发实现微信支付和支付宝支付
  • 原文地址:https://www.cnblogs.com/wangbin/p/3371302.html
Copyright © 2020-2023  润新知