• [C#] 建立UDP连接、发送广播


    说明:

      通过建立本地UdpClient与远程UdpClient进行通讯,亦可直接发送到其他已存在的远程端。

      基本原理:构建一个本地的udpcSend实例,开启多线程进行监听,然后再发送广播。

      案例有字节数组与十六进制字符串相互转换的方法。

    一、案例源码

      窗体的主要代码:FrmMain.cs

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Net;
      8 using System.Net.Sockets;
      9 using System.Text;
     10 using System.Threading;
     11 using System.Threading.Tasks;
     12 using System.Windows.Forms;
     13 
     14 namespace NetworkService
     15 {
     16     public partial class FrmMain : Form
     17     {
     18         public FrmMain()
     19         {
     20             InitializeComponent();
     21 
     22             //string msg = "FF FB 0F";
     23             //byte[] bytes = Encoding.Default.GetBytes(msg);
     24             
     25 
     26             //string res = "";
     27             //for (int i = 0; i < bytes.Length; i++)
     28             //{
     29             //    res += bytes[i].ToString();
     30             //}
     31             //MessageBox.Show(res);
     32 
     33 
     34         }
     35 
     36         //本地收发UDPClient实例
     37         private UdpClient udpcSend;
     38         private UdpClient udpcRecv;
     39         private bool isLocalConneted = false;//本地是否已连接
     40         private Thread thrRecv;//本地监听接收线程
     41 
     42         /// <summary>
     43         /// 【构建本地连接】
     44         ///  20181021
     45         /// </summary>
     46         /// <param name="sender"></param>
     47         /// <param name="e"></param>
     48         private void btnConnect_Click(object sender, EventArgs e)
     49         {
     50             if (cbProtocol.SelectedIndex != 0)
     51             {
     52                 MessageBox.Show("请暂时选择UDP协议!", "系统提示");
     53                 return;
     54             }
     55 
     56             if (string.IsNullOrWhiteSpace(tbLocalIP.Text) || string.IsNullOrWhiteSpace(tbLocalPort.Text))
     57             {
     58                 MessageBox.Show("请填写本地IP和端口", "系统提示");
     59                 return;
     60             }
     61 
     62 
     63             if (!isLocalConneted)//构建本地连接
     64             {
     65                 IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(tbLocalIP.Text), Convert.ToInt32(tbLocalPort.Text));
     66                 udpcSend = new UdpClient(localIpep);
     67 
     68                 btnConnect.Text = "断开";
     69                 isLocalConneted = true;
     70 
     71                 //启动监听接收信息
     72                 BeginListenRecv();
     73             }
     74             else//断开本地连接
     75             {
     76                 //关闭监听线程
     77                 thrRecv.Abort();
     78                 udpcRecv.Close();
     79 
     80                 udpcSend.Close();
     81                 btnConnect.Text = "连接";
     82                 isLocalConneted = false;
     83 
     84 
     85                 ShowMessage(tbRecvMsg, "[OS]:UDP监听已成功关闭");
     86             }
     87         }
     88 
     89         
     90         
     91         /// <summary>
     92         /// 【开始监听】
     93         ///  20181021
     94         /// </summary>
     95         private void BeginListenRecv()
     96         {
     97             udpcRecv = udpcSend;//接收与发送使用同一个实例
     98 
     99             thrRecv = new Thread(ReceiveMessage);
    100             thrRecv.Start();
    101 
    102             ShowMessage(tbRecvMsg, "[OS]:Local UDP 监听已成功启动");
    103 
    104         }
    105 
    106         /// <summary>
    107         /// 【接收信息】
    108         ///  20181021
    109         /// </summary>
    110         private void ReceiveMessage()
    111         {
    112             IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);//接收任何来源的信息
    113             while (true)
    114             {
    115                 byte[] byteRecv = udpcRecv.Receive(ref remoteIpep);
    116                 string message = ByteArrayToHexStringNoBlank(byteRecv);
    117 
    118                 //remoteIpep.Address.ToString() 获取发送源的IP
    119                 ShowMessage(tbRecvMsg, "[Local Recv]:" + remoteIpep.Address + ":" + remoteIpep.Port + "=" + message);
    120 
    121             }
    122 
    123         }
    124 
    125         /// <summary>
    126         /// 【发送消息】
    127         ///  20181021
    128         /// </summary>
    129         /// <param name="obj"></param>
    130         private void SendMessage(object obj)
    131         {
    132             string[] data = (string[])obj;
    133 
    134             //字符串转16进制
    135             byte[] sendBytes = HexStringToByteArray(data[0]);
    136 
    137             //发送到远程IP和端口
    138             IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(data[1]), Convert.ToInt32(data[2]));
    139 
    140             udpcSend.Send(sendBytes, sendBytes.Length, remoteIpep);
    141 
    142             
    143             ShowMessage(tbRecvMsg, "[Local Send]:" + data[0]);
    144             ResetTextBox(tbSendMsg);
    145         }
    146 
    147 
    148         //构建远程服务的收发实例
    149         private UdpClient remoteUdpcSend;
    150         private UdpClient remoteUdpcRecv;
    151         private Thread remoteThrRecv;
    152 
    153         private Thread thrSend;
    154         private bool isRemoteCreated = false;
    155         /// <summary>
    156         /// 【发送消息】
    157         ///  20181021
    158         /// </summary>
    159         /// <param name="sender"></param>
    160         /// <param name="e"></param>
    161         private void btnSend_Click(object sender, EventArgs e)
    162         {
    163             if (string.IsNullOrWhiteSpace(tbRemoteIP.Text) || string.IsNullOrWhiteSpace(tbRemotePort.Text))
    164             {
    165                 MessageBox.Show("远程IP和端口不能为空!", "系统提示");
    166                 return;
    167             }
    168 
    169             if (string.IsNullOrWhiteSpace(tbSendMsg.Text))
    170             {
    171                 MessageBox.Show("发送的消息不能为空!", "系统提示");
    172                 return;
    173             }
    174 
    175             if (!isLocalConneted)
    176             {
    177                 MessageBox.Show("请先建立本地连接!", "系统提示");
    178                 return;
    179             }
    180 
    181             
    182             //构建本地远程
    183             if (cbIsRemoteAsLocal.Checked)//构建本地的远程服务,本地处理
    184             {
    185                 if (!isRemoteCreated)
    186                 {
    187                     IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(tbRemoteIP.Text), Convert.ToInt32(tbRemotePort.Text));//构建远程端口
    188                     remoteUdpcRecv = new UdpClient(remoteIpep);
    189 
    190                     //启动远程的监听
    191                     remoteThrRecv = new Thread(RemoteRecvMessage);
    192                     remoteThrRecv.Start();
    193 
    194                     ShowMessage(tbRecvMsg, "[OS]:Remote UDP 监听启动完成!");
    195                     isRemoteCreated = true;//远程服务已启动
    196                 }
    197                 else
    198                 {
    199                     //发送消息
    200                 }
    201 
    202             }
    203             else
    204             {
    205                 //发送消息,
    206             }
    207 
    208             //发送远程,这里不做处理,直接调用udpcSend发送即可
    209             thrSend = new Thread(new ParameterizedThreadStart(SendMessage));
    210 
    211             string[] param = new string[] { tbSendMsg.Text, tbRemoteIP.Text, tbRemotePort.Text };
    212             thrSend.Start(param);
    213 
    214         }
    215 
    216         /// <summary>
    217         /// 【本地远程发送消息】
    218         ///  20181021
    219         /// </summary>
    220         /// <param name="remoteIpep"></param>
    221         private void RemoteSendMessage(IPEndPoint remoteIpep)
    222         {
    223             remoteUdpcSend = remoteUdpcRecv;
    224 
    225             byte[] msg = Encoding.Default.GetBytes("远程已收到你的消息");
    226 
    227             remoteUdpcSend.Send(msg, msg.Length, remoteIpep);
    228 
    229             ShowMessage(tbRecvMsg, "[Remote Send]:" + "远程已收到你的消息");
    230         }
    231 
    232         /// <summary>
    233         /// 【本地远程接收信息】
    234         ///  20181021
    235         /// </summary>
    236         private void RemoteRecvMessage()
    237         {
    238             IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, 0);//接收任何来源的信息
    239             while (true)
    240             {
    241                 byte[] byteRemoteRecv = remoteUdpcRecv.Receive(ref remoteIpep);
    242                 string message = Encoding.Default.GetString(byteRemoteRecv);
    243 
    244                 //接收到信息
    245                 if (byteRemoteRecv.Length > 0)
    246                 {
    247                     //remoteIpep.Address.ToString() 获取发送源的IP
    248                     ShowMessage(tbRecvMsg, "[Remote Recv]:" + remoteIpep.Address + ":" + remoteIpep.Port + "=" + message);
    249                     
    250                     RemoteSendMessage(remoteIpep);
    251                 }
    252 
    253             }
    254         }
    255 
    256         //更新显示TextBox
    257         delegate void ShowMessageDelegate(TextBox tb, string msg);
    258         private void ShowMessage(TextBox tb, string msg)
    259         {
    260             if (tb.InvokeRequired)
    261             {
    262                 ShowMessageDelegate showMessageDelegate = ShowMessage;
    263                 tb.Invoke(showMessageDelegate, new object[] { tb, msg });
    264             }
    265             else
    266             {
    267                 tb.Text += msg + "
    ";
    268             }
    269         }
    270 
    271         //清空TextBox
    272         delegate void ResetTextBoxDelegate(TextBox tb);
    273         private void ResetTextBox(TextBox tb)
    274         {
    275             if (tb.InvokeRequired)
    276             {
    277                 ResetTextBoxDelegate resetTextBoxDelegate = ResetTextBox;
    278                 tb.Invoke(resetTextBoxDelegate, new object[] { tb });
    279             }
    280             else
    281             {
    282                 tb.Text = "";
    283             }
    284         }
    285 
    286         /// <summary>
    287         /// 【字符串转16进制】
    288         ///  20181021
    289         /// </summary>
    290         /// <param name="s"></param>
    291         /// <returns></returns>
    292         public byte[] HexStringToByteArray(string s)
    293         {
    294             if (s.Length == 0)
    295                 throw new Exception("字符串长度为0");
    296             s = s.Replace(" ", "");
    297             byte[] buffer = new byte[s.Length / 2];
    298             for (int i = 0; i < s.Length; i += 2)
    299                 buffer[i / 2] = Convert.ToByte(s.Substring(i, 2), 16);
    300             return buffer;
    301         }
    302 
    303         /// <summary>
    304         /// 【字节数组转换成十六进制字符串(不带空格)】
    305         ///  20181021
    306         /// </summary>
    307         /// <param name="data">要转换的字节数组</param>
    308         /// <returns>转换后的字符串</returns>
    309         public string ByteArrayToHexStringNoBlank(byte[] data)
    310         {
    311             StringBuilder sb = new StringBuilder(data.Length * 3);
    312             foreach (byte b in data)
    313                 sb.Append(Convert.ToString(b, 16).PadLeft(2, '0') + " ");
    314             return sb.ToString().ToUpper();
    315         }
    316 
    317         /// <summary>
    318         /// 【窗体退出,关闭子线程】
    319         ///  20181021
    320         /// </summary>
    321         /// <param name="sender"></param>
    322         /// <param name="e"></param>
    323         private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
    324         {
    325             Environment.Exit(0);
    326         }
    327 
    328  
    329 
    330 
    331     }
    332 }

    二、界面

      

  • 相关阅读:
    java的构造方法 this 重载
    容器,组件,面板
    首先定义一个5X8的二维数组,然后使用随机数填充满。借助Arrays的方法对二维数组进行排序。
    首先创建一个长度是5的数组,并填充随机数。首先用选择法正排序,然后再对其使用冒泡法倒排序
    创建一个长度是5的数组,并填充随机数。使用for循环或者while循环,对这个数组实现反转效果
    寻找某两个数相除,其结果 离黄金分割点 0.618最近,分母和分子不能同时为偶数 * 分母和分子 取值范围在[1-20]
    密码的自动生成器:密码由大写字母/小写字母/数字组成,生成12位随机密码
    vue倒计时:天时分秒
    tbody设置超出固定的高度出现滚动条,没超出不显示。
    获取某个日期的当前周一的时间
  • 原文地址:https://www.cnblogs.com/reader/p/9835917.html
Copyright © 2020-2023  润新知