[C#] 建立UDP连接、发送广播
说明:
通过建立本地UdpClient与远程UdpClient进行通讯,亦可直接发送到其他已存在的远程端。
基本原理:构建一个本地的udpcSend实例,开启多线程进行监听,然后再发送广播。
案例有字节数组与十六进制字符串相互转换的方法。
一、案例源码
窗体的主要代码:FrmMain.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; namespace NetworkService
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent(); //string msg = "FF FB 0F";
//byte[] bytes = Encoding.Default.GetBytes(msg); //string res = "";
//for (int i = 0; i < bytes.Length; i++)
//{
// res += bytes[i].ToString();
//}
//MessageBox.Show(res); } //本地收发UDPClient实例
private UdpClient udpcSend;
private UdpClient udpcRecv;
private bool isLocalConneted = false;//本地是否已连接
private Thread thrRecv;//本地监听接收线程 /// <summary>
/// 【构建本地连接】
/// 20181021
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnConnect_Click(object sender, EventArgs e)
{
if (cbProtocol.SelectedIndex != )
{
MessageBox.Show("请暂时选择UDP协议!", "系统提示");
return;
} if (string.IsNullOrWhiteSpace(tbLocalIP.Text) || string.IsNullOrWhiteSpace(tbLocalPort.Text))
{
MessageBox.Show("请填写本地IP和端口", "系统提示");
return;
} if (!isLocalConneted)//构建本地连接
{
IPEndPoint localIpep = new IPEndPoint(IPAddress.Parse(tbLocalIP.Text), Convert.ToInt32(tbLocalPort.Text));
udpcSend = new UdpClient(localIpep); btnConnect.Text = "断开";
isLocalConneted = true; //启动监听接收信息
BeginListenRecv();
}
else//断开本地连接
{
//关闭监听线程
thrRecv.Abort();
udpcRecv.Close(); udpcSend.Close();
btnConnect.Text = "连接";
isLocalConneted = false; ShowMessage(tbRecvMsg, "[OS]:UDP监听已成功关闭");
}
} /// <summary>
/// 【开始监听】
/// 20181021
/// </summary>
private void BeginListenRecv()
{
udpcRecv = udpcSend;//接收与发送使用同一个实例 thrRecv = new Thread(ReceiveMessage);
thrRecv.Start(); ShowMessage(tbRecvMsg, "[OS]:Local UDP 监听已成功启动"); } /// <summary>
/// 【接收信息】
/// 20181021
/// </summary>
private void ReceiveMessage()
{
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, );//接收任何来源的信息
while (true)
{
byte[] byteRecv = udpcRecv.Receive(ref remoteIpep);
string message = ByteArrayToHexStringNoBlank(byteRecv); //remoteIpep.Address.ToString() 获取发送源的IP
ShowMessage(tbRecvMsg, "[Local Recv]:" + remoteIpep.Address + ":" + remoteIpep.Port + "=" + message); } } /// <summary>
/// 【发送消息】
/// 20181021
/// </summary>
/// <param name="obj"></param>
private void SendMessage(object obj)
{
string[] data = (string[])obj; //字符串转16进制
byte[] sendBytes = HexStringToByteArray(data[]); //发送到远程IP和端口
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(data[]), Convert.ToInt32(data[])); udpcSend.Send(sendBytes, sendBytes.Length, remoteIpep); ShowMessage(tbRecvMsg, "[Local Send]:" + data[]);
ResetTextBox(tbSendMsg);
} //构建远程服务的收发实例
private UdpClient remoteUdpcSend;
private UdpClient remoteUdpcRecv;
private Thread remoteThrRecv; private Thread thrSend;
private bool isRemoteCreated = false;
/// <summary>
/// 【发送消息】
/// 20181021
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(tbRemoteIP.Text) || string.IsNullOrWhiteSpace(tbRemotePort.Text))
{
MessageBox.Show("远程IP和端口不能为空!", "系统提示");
return;
} if (string.IsNullOrWhiteSpace(tbSendMsg.Text))
{
MessageBox.Show("发送的消息不能为空!", "系统提示");
return;
} if (!isLocalConneted)
{
MessageBox.Show("请先建立本地连接!", "系统提示");
return;
} //构建本地远程
if (cbIsRemoteAsLocal.Checked)//构建本地的远程服务,本地处理
{
if (!isRemoteCreated)
{
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse(tbRemoteIP.Text), Convert.ToInt32(tbRemotePort.Text));//构建远程端口
remoteUdpcRecv = new UdpClient(remoteIpep); //启动远程的监听
remoteThrRecv = new Thread(RemoteRecvMessage);
remoteThrRecv.Start(); ShowMessage(tbRecvMsg, "[OS]:Remote UDP 监听启动完成!");
isRemoteCreated = true;//远程服务已启动
}
else
{
//发送消息
} }
else
{
//发送消息,
} //发送远程,这里不做处理,直接调用udpcSend发送即可
thrSend = new Thread(new ParameterizedThreadStart(SendMessage)); string[] param = new string[] { tbSendMsg.Text, tbRemoteIP.Text, tbRemotePort.Text };
thrSend.Start(param); } /// <summary>
/// 【本地远程发送消息】
/// 20181021
/// </summary>
/// <param name="remoteIpep"></param>
private void RemoteSendMessage(IPEndPoint remoteIpep)
{
remoteUdpcSend = remoteUdpcRecv; byte[] msg = Encoding.Default.GetBytes("远程已收到你的消息"); remoteUdpcSend.Send(msg, msg.Length, remoteIpep); ShowMessage(tbRecvMsg, "[Remote Send]:" + "远程已收到你的消息");
} /// <summary>
/// 【本地远程接收信息】
/// 20181021
/// </summary>
private void RemoteRecvMessage()
{
IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Any, );//接收任何来源的信息
while (true)
{
byte[] byteRemoteRecv = remoteUdpcRecv.Receive(ref remoteIpep);
string message = Encoding.Default.GetString(byteRemoteRecv); //接收到信息
if (byteRemoteRecv.Length > )
{
//remoteIpep.Address.ToString() 获取发送源的IP
ShowMessage(tbRecvMsg, "[Remote Recv]:" + remoteIpep.Address + ":" + remoteIpep.Port + "=" + message); RemoteSendMessage(remoteIpep);
} }
} //更新显示TextBox
delegate void ShowMessageDelegate(TextBox tb, string msg);
private void ShowMessage(TextBox tb, string msg)
{
if (tb.InvokeRequired)
{
ShowMessageDelegate showMessageDelegate = ShowMessage;
tb.Invoke(showMessageDelegate, new object[] { tb, msg });
}
else
{
tb.Text += msg + "\r\n";
}
} //清空TextBox
delegate void ResetTextBoxDelegate(TextBox tb);
private void ResetTextBox(TextBox tb)
{
if (tb.InvokeRequired)
{
ResetTextBoxDelegate resetTextBoxDelegate = ResetTextBox;
tb.Invoke(resetTextBoxDelegate, new object[] { tb });
}
else
{
tb.Text = "";
}
} /// <summary>
/// 【字符串转16进制】
/// 20181021
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public byte[] HexStringToByteArray(string s)
{
if (s.Length == )
throw new Exception("字符串长度为0");
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / ];
for (int i = ; i < s.Length; i += )
buffer[i / ] = Convert.ToByte(s.Substring(i, ), );
return buffer;
} /// <summary>
/// 【字节数组转换成十六进制字符串(不带空格)】
/// 20181021
/// </summary>
/// <param name="data">要转换的字节数组</param>
/// <returns>转换后的字符串</returns>
public string ByteArrayToHexStringNoBlank(byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * );
foreach (byte b in data)
sb.Append(Convert.ToString(b, ).PadLeft(, '') + " ");
return sb.ToString().ToUpper();
} /// <summary>
/// 【窗体退出,关闭子线程】
/// 20181021
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
Environment.Exit();
} }
}
二、界面

[C#] 建立UDP连接、发送广播的更多相关文章
- python实现建立udp通信
实现代码如下: #udp协议通信import socket,timeclass UdpConnect: def get_udp(self,ip,port,message): #建立udp连接 myso ...
- Android 通过局域网udp广播自动建立socket连接
Android开发中经常会用到socket通讯.由于项目需要,最近研究了一下这方面的知识. 需求是想通过wifi实现android移动设备和android平台的电视之间的文件传输与控制. 毫无疑问这中 ...
- 通过UDP建立TCP连接
解释 通过UDP广播查询服务器的IP地址,然后再建立TCP点对点连接. 应用场景 在服务器IP未知时,并且已知服务器与客户端明确在一个局域网或者允许组播的子网下. 通过UDP发现服务器地址然后再进行T ...
- 网游中的网络编程3:在UDP上建立虚拟连接
目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...
- udp发送广播消息
import socket if __name__ == '__main__': # 创建udpsocket udp_socket = socket.socket(socket.AF_INET, so ...
- UDP 单播、广播和多播
阅读目录(Content) 一.UDP广播 二.UDP多播 1.多播(组播)的概念 2.广域网的多播 三.UDP广播与单播 广播与单播的比较 使用UDP协议进行信息的传输之前不需要建议连接.换句话说就 ...
- UDP 单播、广播、多播
一.UDP广播 广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机.值得强调的是:本地广播信息是不会被路由器转发.当然 ...
- HTTP协议用的TCP但是只建立单向连接
作者:IronTech链接:https://www.zhihu.com/question/20085992/answer/71742030来源:知乎著作权归作者所有,转载请联系作者获得授权. 下面的解 ...
- Linux 建立 TCP 连接的超时时间分析(解惑)
Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝 ...
随机推荐
- ssh,公钥和私钥,远程复制
ssh,公钥和私钥,远程复制 1.openssh 是一个提供远程访问控制的软件 2.ssh 远程主机用户@远程主机ip地址 ssh root@172.25.254.1 The authenticity ...
- python面向对象-封装-property-接口-抽象-鸭子类型-03
封装 什么是封装: # 将复杂的丑陋的隐私的细节隐藏到内部,对外提供简单的使用接口 或 # 对外隐藏内部实现细节,并提供访问的接口 为什么需要封装 1.为了保证关键数据的安全性 2.对外部隐藏内部的实 ...
- 转 java - 如何判断单链表有环
转自 https://blog.csdn.net/u010983881/article/details/78896293 1.穷举遍历 首先从头节点开始,依次遍历单链表的每一个节点.每遍历到一个新节点 ...
- lr录制选项设置代理
解决录制时浏览器打不开录制时录不到脚本等浏览器兼容问题一.lr录制选项设置代理1.点击Options 2.点击Port Mapping→Newentrv 3.lr代理设置 ·Socket Servic ...
- 初始SpringMVC 完整版
初始SpringMVC 1.SpringMVC 也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的. 2.Java EE ...
- vue使用video.js解决m3u8视频播放格式
今天被这个关于m3u8视频播放不了搞了一下午,这个项目所有的视频流都是m3u8格式的,后台给我们返回的都是m3u8格式的视频流,解决了好长时间,看了好多博客,只有这个博客给我点启发,去解决这个问题,请 ...
- isMemberOfClass、isKindOfClass原理分析
isMemberOfClass - 调用者必须是传入的类的实例对象才返回YES- 判断调用者是否是传入对象的实例,别弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的 ...
- 【Algorithm】选择排序法
简单的选择排序法思想: * 首先找到数组中最小的元素,将它和数组第一个元素互换位置(如果第一个元素就是最小那么它就和自己交换). * 其次,在剩下的元素中找到最小的元素,将它与数组的第二个元素互换位置 ...
- C++实现反射
之前碰到过一个问题,C++中如何通过一个字符串生成一个类. C++是不支持通过类名称字符串”ClassXX”来生成对象的,也就是说我们可以使用 new ClassXX 来生成对象,但是不能通过 new ...
- python3 实现多域名批量访问特定目录(一)
渗透测试之批量处理同一框架CMS系统漏洞 当我们做多网站的渗透测试时,会发现很多站点采用的都是同类型的CMS框架,只要我们发现一个漏洞,那么我们可以批量处理这一类站点,高效测试,如果不知道该站点的框架 ...