说明:

  通过建立本地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连接、发送广播的更多相关文章

  1. python实现建立udp通信

    实现代码如下: #udp协议通信import socket,timeclass UdpConnect: def get_udp(self,ip,port,message): #建立udp连接 myso ...

  2. Android 通过局域网udp广播自动建立socket连接

    Android开发中经常会用到socket通讯.由于项目需要,最近研究了一下这方面的知识. 需求是想通过wifi实现android移动设备和android平台的电视之间的文件传输与控制. 毫无疑问这中 ...

  3. 通过UDP建立TCP连接

    解释 通过UDP广播查询服务器的IP地址,然后再建立TCP点对点连接. 应用场景 在服务器IP未知时,并且已知服务器与客户端明确在一个局域网或者允许组播的子网下. 通过UDP发现服务器地址然后再进行T ...

  4. 网游中的网络编程3:在UDP上建立虚拟连接

    目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...

  5. udp发送广播消息

    import socket if __name__ == '__main__': # 创建udpsocket udp_socket = socket.socket(socket.AF_INET, so ...

  6. UDP 单播、广播和多播

    阅读目录(Content) 一.UDP广播 二.UDP多播 1.多播(组播)的概念 2.广域网的多播 三.UDP广播与单播 广播与单播的比较 使用UDP协议进行信息的传输之前不需要建议连接.换句话说就 ...

  7. UDP 单播、广播、多播

    一.UDP广播 广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机.值得强调的是:本地广播信息是不会被路由器转发.当然 ...

  8. HTTP协议用的TCP但是只建立单向连接

    作者:IronTech链接:https://www.zhihu.com/question/20085992/answer/71742030来源:知乎著作权归作者所有,转载请联系作者获得授权. 下面的解 ...

  9. Linux 建立 TCP 连接的超时时间分析(解惑)

    Linux 系统默认的建立 TCP 连接的超时时间为 127 秒,对于许多客户端来说,这个时间都太长了, 特别是当这个客户端实际上是一个服务的时候,更希望能够尽早失败,以便能够选择其它的可用服务重新尝 ...

随机推荐

  1. python课堂整理7---集合

    前面小节: sep 用来控制每个元素间的间隔符号 print("alex", "dabai", "liu", sep = "&qu ...

  2. k8s1.9.0安装--环境准备

    一.预先准备环境 1. 准备服务器 这里准备了三台centos虚拟机,每台一核cpu和2G内存,配置好root账户,并安装好了docker,后续的所有操作都是使用root账户.虚拟机具体信息如下表: ...

  3. 利用git 找到应该对问题代码负责的人--代码定责

    场景 有时候突然发现 某部分代码存在明显的问题,代码作者的态度需要调整. 或者发现某些代码存在特意留下的bug或漏洞,代码作者需要出来担责. 这时候我们就需要找出来 需要为有问题代码承担责任的同事,或 ...

  4. python正则-re的使用

    今天在刷题的时候用到了正则,用的过程中就感觉有点不太熟练了,很久没有用正则都有点忘了.所以现在呢,我们就一起来review一下python中正则模块re的用法吧. 今天是review,所以一些基础的概 ...

  5. python-crud

    Python Fast CRUD https://github.com/aleimu/python-crud 目的 本项目采用了一系列Python中比较流行的组件,可以以本项目为基础快速搭建Restf ...

  6. TIJ学习--RTTI(Runtime-Time Type Identification)

    TIJ学习--RTTI(Runtime-Time Type Identification) RTTI 运行时类型检查机制 获取一个类的Class引用的三种方法 class TestClass{} Te ...

  7. Django websocket之web端实时查看日志实践案例

    这是Django Channels系列文章的第二篇,以web端实现tailf的案例讲解Channels的具体使用以及跟Celery的结合 通过上一篇<Django使用Channels实现WebS ...

  8. win10去除快捷方式小箭头

    切忌删除注册表项: HKEY_CLASSES_ROOT -> lnkfile -> IsShortcut 这个方法以前是可以的,但是在2018年之后更新的系统就会出现任务栏图标打不开的情况 ...

  9. linux杂货铺

    vmware虚拟机克隆后网卡不能使用 解决方法如下 cat /etc/udev/rules.d/70-persistent-net.rules1.将eth0这行注释掉或者删除,这里记载的还是克隆系统时 ...

  10. Flask+APScheduler定时任务

    1.安装依赖 pip install flask_apscheduler 2.使用定时任务 ```python from flask import Flask from flask_apschedul ...