一、程序实现

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. codevs——1019 集合论与图论

    1019 集合论与图论  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 集合论与图论对于小松来说 ...

  2. Memcached集群之通过Repcached实现主从复制(待实践)

    暂时了解有这东西,不搭建了. Mamcached可以通过Repcached实现主从复制.有以下优缺点: 优点: 1.能够实现Cache的冗余功能 2.主从之间可以互相读写(亮点) 参考: http:/ ...

  3. 爱普生L201

    http://tech.sina.com.cn/b/2011-03-29/05481698131.shtml

  4. iText输出中文的三种字体选择方式

    1.使用iTextAsian.jar中的字体    BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",Bas ...

  5. JAVA WEB接口开发简述

    目录 1. JAVA WEB接口开发简述 1.1. 基本了解 1.2. 提供接口 1.3. 调用接口 1. JAVA WEB接口开发简述 1.1. 基本了解 当我们想去访问其他网站的接口时候,而又不想 ...

  6. java代码判断文件类型(判断文件后缀名)

    1.两点需要注意 1.string.spilt("\\.")分割字符串成子字符串数组,以“.”分割,必须写成string.spilt("\\.")的方式,不能写 ...

  7. iOS自己定义返回button(不影响返回手势)

    此方法能够自己定义返回button,且不影响返回手势. 新方法: self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] in ...

  8. RAD 极速应用开发 Spring ROO 入门样例

    官网                                      http://projects.spring.io/spring-roo/ Spring ROO in action   ...

  9. HDU1215--七夕节

    找出小于N的全部因子的和,N比較大,非常明显要打表来做,不然肯定会超时 方法就是枚举范围内每一个整数.然后再枚举范围内这个整数的全部的倍数,加上这个数 由于这个整数的倍数中一定含有这个整数因子,这样速 ...

  10. H264 层次构成[2]

    H264层次构成 H264标准是由JVT(Joint Video Team,视频联合工作组)组织提出的新一代数字视频编码标准.JVT于2001年12月在泰国Pattaya成立.它由ITU-T的VCEG ...