一、程序实现

UDP广播程序的实现代码:

 using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms; namespace UDPBroadcast
{
/// <summary>
/// 在界面上,用户可以设置本地进程的IP地址和端口号,并将地址加入某个组播组;
/// 可以输入发送消息的目的组的地址,并且勾选“广播”复选框将采用广播的方式发送信息
/// 在界面上点击“接受按钮”就启动接收线程,这样程序就可以接收广播或组播的信息
/// </summary>
public partial class UdpBroadcasefrm : Form
{
private UdpClient sendUdpClient;
private UdpClient receiveUdpClient;
// 组播IP地址
IPEndPoint broadcastIpEndPoint;
public UdpBroadcasefrm()
{
InitializeComponent();
IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());
tbxlocalip.Text = ips[].ToString();
tbxlocalport.Text = "";
// 默认组,组播地址是有范围
// 具体关于组播和广播的介绍参照我上一篇博客UDP编程
// 本地组播组
tbxGroupIp.Text = "224.0.0.1";
// 发送到的组播组
tbxSendToGroupIp.Text = "224.0.0.1";
} // 设置加入组
private void chkbxJoinGtoup_Click(object sender, EventArgs e)
{
if (chkbxJoinGtoup.Checked == true)
{
tbxGroupIp.Enabled = false;
}
else
{
tbxGroupIp.Enabled = true;
tbxGroupIp.Focus();
}
} // 选择发送模式后设置
private void chkbxBroadcast_Click(object sender, EventArgs e)
{
if (chkbxBroadcast.Checked == true)
{
tbxSendToGroupIp.Enabled = false;
}
else
{
tbxSendToGroupIp.Enabled = true;
tbxSendToGroupIp.Focus();
}
} // 发送消息
private void btnSend_Click(object sender, EventArgs e)
{
if (tbxMessageSend.Text == "")
{
MessageBox.Show("消息内容不能为空!","提示");
return;
} // 根据选择的模式发送信息
if (chkbxBroadcast.Checked == true)
{
// 广播模式(自动获得子网中的IP广播地址)
broadcastIpEndPoint = new IPEndPoint(IPAddress.Broadcast, );
}
else
{
// 组播模式
broadcastIpEndPoint = new IPEndPoint(IPAddress.Parse(tbxSendToGroupIp.Text), );
} // 启动发送线程发送消息
Thread sendThread = new Thread(SendMessage);
sendThread.Start(tbxMessageSend.Text);
} // 发送消息
private void SendMessage(object obj)
{
string message = obj.ToString();
byte[] messagebytes = Encoding.Unicode.GetBytes(message);
sendUdpClient = new UdpClient();
// 发送消息到组播或广播地址
sendUdpClient.Send(messagebytes, messagebytes.Length, broadcastIpEndPoint);
sendUdpClient.Close(); // 清空编辑消息框
ResetMessageText(tbxMessageSend);
} // 利用委托回调机制来实现界面上的消息清空操作
delegate void ResetMessageTextCallBack(TextBox textbox);
private void ResetMessageText(TextBox textbox)
{
if (textbox.InvokeRequired)
{
ResetMessageTextCallBack resetMessageCallback = ResetMessageText;
textbox.Invoke(resetMessageCallback, new object[] { textbox });
}
else
{
textbox.Clear();
textbox.Focus();
}
} // 接收消息
private void btnReceive_Click(object sender, EventArgs e)
{
chkbxJoinGtoup.Enabled = false;
// 创建接收套接字
IPAddress localIp = IPAddress.Parse(tbxlocalip.Text);
IPEndPoint localIpEndPoint = new IPEndPoint(localIp, int.Parse(tbxlocalport.Text));
receiveUdpClient = new UdpClient(localIpEndPoint);
// 加入组播组
if (chkbxJoinGtoup.Checked == true)
{
receiveUdpClient.JoinMulticastGroup(IPAddress.Parse(tbxGroupIp.Text));
receiveUdpClient.Ttl = ;
} // 启动接受线程
Thread threadReceive = new Thread(ReceiveMessage);
threadReceive.Start();
} // 接受消息方法
private void ReceiveMessage()
{
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, );
while (true)
{
try
{
// 关闭receiveUdpClient时此时会产生异常
byte[] receiveBytes = receiveUdpClient.Receive(ref remoteIpEndPoint);
string receivemessage = Encoding.Unicode.GetString(receiveBytes); // 显示消息内容
ShowMessage(lstMessageBox, string.Format("{0}[{1}]", remoteIpEndPoint, receivemessage));
}
catch
{
break;
}
}
}
// 通过委托回调机制显示消息内容
delegate void ShowMessageCallBack(ListBox listbox,string text);
private void ShowMessage(ListBox listbox, string text)
{
if (listbox.InvokeRequired)
{
ShowMessageCallBack showmessageCallback = ShowMessage;
listbox.Invoke(showmessageCallback, new object[] { listbox, text });
}
else
{
listbox.Items.Add(text);
listbox.SelectedIndex = listbox.Items.Count - ;
listbox.ClearSelected();
}
} // 清空消息列表
private void btnClear_Click(object sender, EventArgs e)
{
lstMessageBox.Items.Clear();
} // 停止接收
private void btnStop_Click(object sender, EventArgs e)
{
chkbxJoinGtoup.Enabled =true;
receiveUdpClient.Close();
} }
}

广播演示结果(接收端直接点接收按钮后开启接受线程,在发送端勾选“广播选项”输入发送信息点发送按钮后的界面如下):

下面通过把接收端加入组后的结果,首先终止接收线程,然后勾选“加入组”复选框,然后单击“接收”按钮重新开启接收线程,输出结果如下:

从广播演示的两个情况可以看出广播消息会同时向网上的一切进程转发,无论这个进程是独立的还是加入了某个组播组中的进程,都可以接收广播消息

下面演示下组播的结果:

如果把接收端的组地址改为224.0.0.3时,此时发送端发送的消息“组播演示2”将不会发送到不同的组播地址,则接收端就接收不到此时的消息。

从组播结果中可以看出只有加入组播地址224.0.0.2的进程才能接收到信息。

需要注意的地方是:从前面的截图中可以看出,不论是广播还是组播,仅仅从收到的信息无从知道发送给它的进程的端口号,所以广播和组播消息都是匿名发送,并且通过对UDP广播和组播的理解可以简单实现一个消息群发的功能(QQ的群里聊天就是这个原理)。

二、 总结

本专题主要是针对上一专题的补充——实现一个简单的UDP广播(组播)程序,通过这样一个发送端可以发送给在组播地址中的所有用户和所有子网中的所有用户。本专题可以说是对UDP编程的一个扩充吧,希望大家看了本专题后可以对UDP协议有大致的理解。在下一个专题中会和大家介绍下P2P编程的相关知识。

全部源码地址:http://files.cnblogs.com/zhili/UDPBroadcast.zip

专题七:UDP编程补充——UDP广播程序的实现的更多相关文章

  1. [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现

    转自:http://www.cnblogs.com/zhili/archive/2012/09/03/2666974.html 上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享 ...

  2. 转:【专题七】UDP编程补充——UDP广播程序的实现

    上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享下,本专题主要介绍下如何实现UDP广播的程序,下面就直接介绍实现过程和代码以及运行的结果. 一.程序实现 UDP广播程序的实现代 ...

  3. 【网络编程1】网络编程基础-TCP、UDP编程

    网络基础知识 网络模型知识 OSI七层模型:(Open Systems Interconnection Reference Model)开放式通信系统互联参考模型,是国际标准化组织(ISO)提出的一个 ...

  4. 37 - 网络编程-UDP编程

    目录 1 UDP协议 2 UDP通信流程 3 UDP编程 3.1 构建服务端 3.3 常用方法 4 聊天室 5 UDP协议应用 1 UDP协议 UDP是面向无连接的协议,使用UDP协议时,不需要建立连 ...

  5. [C# 网络编程系列]专题六:UDP编程

    转自:http://www.cnblogs.com/zhili/archive/2012/09/01/2659167.html 引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当 ...

  6. 转:【专题六】UDP编程

    引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当的另一个传输层协议,它也是当下流行的很多主流网络应用(例如QQ.MSN和Skype等一些即时通信软件传输层都是应用UDP协议的) ...

  7. 专题六:UDP编程

    引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当的另一个传输层协议,它也是当下流行的很多主流网络应用(例如QQ.MSN和Skype等一些即时通信软件传输层都是应用UDP协议的) ...

  8. UNIX网络编程——基于UDP协议的网络程序

    一.下图是典型的UDP客户端/服务器通讯过程 下面依照通信流程,我们来实现一个UDP回射客户/服务器: #include <sys/types.h> #include <sys/so ...

  9. java 网络编程基础 UDP协议的Socket:DatagramSocket;广播Socket:MulticastSocket

    什么是UDP协议: UDP协议是一种不可靠的网络协议,它在通信实例的两端各建立一个Socket 但这两个 Socket之间并没有虚拟链路,这两个Socket只是发送.接收数据报的对象.Java 提供了 ...

随机推荐

  1. Ubuntu 16.04使用sudo apt-get -f install解决依赖时的注意事项(重点)

    注意:在觉得软件依赖时,一般使用sudo apt-get -f install,但是也是非常危险的,尤其时一些软件需要删除某些依赖时,会导致原有安装的软件全部卸载.所以使用此命令时要时刻注意输出的这条 ...

  2. 保持WCF服务端与客户端的长连接

    背景 客户端与服务端使用WCF建立连接后:1.可能长时间不对话(调用服务操作):2.客户端的网络不稳定. 为服务端与客户端两边都写“心跳检测”代码?不愿意. 解决 设置inactivityTimeou ...

  3. Ansible 2.0公布

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/ansible-2-released 经过了一年的开发工作后,Ansib ...

  4. ArcGIS Python 编码问题

    吐槽一下ArcGIS自带的 Python IDE, 没有代码补全 没有函数提示 没有代码折叠 没有行号 撤销操作还有问题 字符编码还有各种问题 .........   花了2天时间才琢磨出来的经验 环 ...

  5. C#——await与async实现多线程异步编程

    曾经,我们也许用过Thread.在主线程运行的时候.新开还有一个新线程,来运行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,可是又感觉非常熟悉的样子,感觉是线程那块儿的东西, ...

  6. HDU 4983 Goffi and GCD(数论)

    HDU 4983 Goffi and GCD 思路:数论题.假设k为2和n为1.那么仅仅可能1种.其它的k > 2就是0种,那么事实上仅仅要考虑k = 1的情况了.k = 1的时候,枚举n的因子 ...

  7. 扩展GCD 中国剩余定理(CRT) 乘法逆元模版

    extend_gcd: 已知 a,b (a>=0,b>=0) 求一组解 (x,y) 使得 (x,y)满足 gcd(a,b) = ax+by 以下代码中d = gcd(a,b).顺便求出gc ...

  8. 【动态规划】Dynamic Programming

    动态规划 一.动态规划 动态规划(Dynamic Programming)是一种设计的技巧,是解决多阶段决策过程最优化问题的通用方法. 基本思想:将待求解问题分解成若干个子问题,先求解子问题,然后从这 ...

  9. Django打造大型企业官网(七)

    4.13.新闻列表tab栏布局完成 templates/news/index.html <div class="list-outer-group"> <ul cl ...

  10. web 开发之js---js 实现地址栏的表单提交加密编码

    以前在做嵌入式web时,曾经想过cgi加密,原来js可以直接实现,太好了,这里js在客户端实现编码和解码 一.在地址栏直接输入:javascript:str=encodeURI("笃行天下& ...