注意:客户端和服务器实现基本一致,本地host和port和多播的host和port可以一样

(1)多播

1.将本地host加入多播组中,只有加入多播组的成员才能接受同组的节点发送的多播

MulticastOption mcastOption = new MulticastOption(IPAddress.Parse(MultiCastHost), IPAddress.Parse(localHost));
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption);

2.将本地host移出多播组中

socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DropMembership, mcastOption);

3.多播生存时间 millisecond

socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 10);

发送信息指定MultiCastHost发送

(2)广播

开启广播

socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);

发送信息指定255.255.255.255发送

参考:MSDN

    public class UdpServiceSocket
{
private readonly string broadCastHost = "255.255.255.255"; //接收数据事件
public Action<string> recvMessageEvent = null;
//发送结果事件
public Action<int> sendResultEvent = null; //接收缓存数组
private byte[] recvBuff = null;
//发送缓存数组
private byte[] sendBuff = null;
//用于发送数据的SocketAsyncEventArgs
private SocketAsyncEventArgs sendEventArg = null;
//用于接收数据的SocketAsyncEventArgs
private SocketAsyncEventArgs recvEventArg = null;
//监听socket
private Socket socket = null;
//用于socket发送和接收的缓存区大小
private int bufferSize = 1024;
//udp服务器绑定地址
private string localHost = "";
//udp服务器监听端口
private int localPort = 0;
//udp广播组地址
private string MultiCastHost = "";
//udp广播组端口
private int MultiCastPort = 0; /// <summary>
/// 构造函数
/// </summary>
/// <param name="bufferSize">用于socket发送和接受的缓存区大小</param>
public UdpServiceSocket()
{
//设置用于发送数据的SocketAsyncEventArgs
sendBuff = new byte[bufferSize];
sendEventArg = new SocketAsyncEventArgs();
sendEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
sendEventArg.SetBuffer(sendBuff, 0, bufferSize);
//设置用于接受数据的SocketAsyncEventArgs
recvBuff = new byte[bufferSize];
recvEventArg = new SocketAsyncEventArgs();
recvEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
recvEventArg.SetBuffer(recvBuff, 0, bufferSize);
} /// <summary>
/// 开启udp服务器,等待udp客户端数据(设置广播)
/// </summary>
public void Start(string localHost, int localPort)
{
if (string.IsNullOrEmpty(localHost))
throw new ArgumentNullException("localHost cannot be null");
if (localPort < 1 || localPort > 65535)
throw new ArgumentOutOfRangeException("localPort is out of range"); this.localHost = localHost;
this.localPort = localPort; try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //设置广播
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(localHost), localPort);
socket.Bind(endpoint);//设置监听地址和端口
StartRecvFrom();
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 开启udp服务器,等待udp客户端数据(设置多播,广播)
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
public void Start(string localHost, int localPort, string MultiCastHost, int MultiCastPort)
{
if (string.IsNullOrEmpty(localHost))
throw new ArgumentNullException("localHost cannot be null");
if (localPort < 1 || localPort > 65535)
throw new ArgumentOutOfRangeException("localPort is out of range"); if (string.IsNullOrEmpty(MultiCastHost))
throw new ArgumentNullException("MultiCastHost cannot be null");
if (MultiCastPort < 1 || MultiCastPort > 65535)
throw new ArgumentOutOfRangeException("MultiCastPort is out of range"); this.localHost = localHost;
this.localPort = localPort;
this.MultiCastHost = MultiCastHost;
this.MultiCastPort = MultiCastPort; try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //设置广播
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); //设置多播
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, true);
MulticastOption mcastOption = new MulticastOption(IPAddress.Parse(MultiCastHost), IPAddress.Parse(localHost));
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption); IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(localHost), localPort);
socket.Bind(endpoint);//设置监听地址和端口
StartRecvFrom();
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 开始接受udp客户端发送的数据
/// </summary>
private void StartRecvFrom()
{
recvEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
bool willRaiseEvent = socket.ReceiveFromAsync(recvEventArg);
if (!willRaiseEvent)
{
ProcessReceive(recvEventArg);
}
} /// <summary>
/// socket.sendAsync和socket.recvAsync的完成回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void IO_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.ReceiveFrom:
ProcessReceive(e);
break;
case SocketAsyncOperation.SendTo:
ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
} /// <summary>
/// 处理接收到的udp客户端数据
/// </summary>
/// <param name="e"></param>
private void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
if (recvMessageEvent != null)
//一定要指定GetString的长度
recvMessageEvent(Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred)); StartRecvFrom();
}
else
{
Restart();
}
} /// <summary>
/// 处理udp服务器发送的结果
/// </summary>
/// <param name="e"></param>
private void ProcessSend(SocketAsyncEventArgs e)
{
AsyncUserToken token = (AsyncUserToken)e.UserToken;
if (e.SocketError == SocketError.Success)
{
if (sendResultEvent != null)
sendResultEvent(e.BytesTransferred);
}
else
{
if (sendResultEvent != null)
sendResultEvent(e.BytesTransferred);
Restart();
}
} /// <summary>
/// 关闭udp服务器
/// </summary>
public void CloseSocket()
{
if (socket == null)
return; try
{
socket.Shutdown(SocketShutdown.Both);
}
catch { } try
{
socket.Close();
}
catch { }
} /// <summary>
/// 重新启动udp服务器
/// </summary>
public void Restart()
{
CloseSocket();
if (string.IsNullOrEmpty(MultiCastHost))
Start(localHost, localPort, MultiCastHost, MultiCastPort);
else
Start(localHost, localPort);
} /// <summary>
/// 发送广播
/// </summary>
/// <param name="message"></param>
public void SendMessageByBroadcast(string message)
{
if (socket == null)
throw new ArgumentNullException("socket cannot be null");
if (string.IsNullOrEmpty(message))
throw new ArgumentNullException("message cannot be null"); byte[] buff = Encoding.UTF8.GetBytes(message);
if (buff.Length > bufferSize)
throw new ArgumentOutOfRangeException("message is out off range"); sendEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(broadCastHost), localPort);
buff.CopyTo(sendEventArg.Buffer, 0);
sendEventArg.SetBuffer(0, buff.Length);
bool willRaiseEvent = socket.SendToAsync(sendEventArg);
if (!willRaiseEvent)
{
ProcessSend(sendEventArg);
}
} /// <summary>
/// 发送单播
/// </summary>
/// <param name="message"></param>
public void SendMessageByUnicast(string message, string destHost, int destPort)
{
if (socket == null)
throw new ArgumentNullException("socket cannot be null");
if (string.IsNullOrEmpty(message))
throw new ArgumentNullException("message cannot be null");
if (string.IsNullOrEmpty(destHost))
throw new ArgumentNullException("destHost cannot be null");
if (destPort < 1 || destPort > 65535)
throw new ArgumentOutOfRangeException("destPort is out of range"); byte[] buff = Encoding.UTF8.GetBytes(message);
if (buff.Length > bufferSize)
throw new ArgumentOutOfRangeException("message is out off range"); sendEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(destHost), destPort);
buff.CopyTo(sendEventArg.Buffer, 0);
sendEventArg.SetBuffer(0, buff.Length);
bool willRaiseEvent = socket.SendToAsync(sendEventArg);
if (!willRaiseEvent)
{
ProcessSend(sendEventArg);
}
} /// <summary>
/// 发送组播(多播)
/// </summary>
/// <param name="message"></param>
public void SendMessageByMulticast(string message)
{
if (socket == null)
throw new ArgumentNullException("socket cannot be null");
if (string.IsNullOrEmpty(message))
throw new ArgumentNullException("message cannot be null");
if (string.IsNullOrEmpty(MultiCastHost))
throw new ArgumentNullException("MultiCastHost cannot be null");
if (MultiCastPort < 1 || MultiCastPort > 65535)
throw new ArgumentOutOfRangeException("MultiCastPort is out of range"); byte[] buff = Encoding.UTF8.GetBytes(message);
if (buff.Length > bufferSize)
throw new ArgumentOutOfRangeException("message is out off range"); sendEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(MultiCastHost), MultiCastPort);
buff.CopyTo(sendEventArg.Buffer, 0);
sendEventArg.SetBuffer(0, buff.Length);
bool willRaiseEvent = socket.SendToAsync(sendEventArg);
if (!willRaiseEvent)
{
ProcessSend(sendEventArg);
}
}
}

  

  

udp单播,广播,多播实现(ReceiveFromAsync,SendToAsync)的更多相关文章

  1. UDP单播、多播、广播

    一.UDP广播 广播使用的特殊的IP地址:最后一位是255时的IP地址是给广播预留的IP地址,如:192.168.88.255 广播UDP与单播UDP的区别就是IP地址不同,广播使用广播地址255.2 ...

  2. UDP 单播、广播和多播

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

  3. UDP 单播、广播、多播

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

  4. 以QQ举例 说明计算机网络中的一些概念区别(TCP与UDP,广播与单播)

    QQ 中的 广播与单播 今天简单地学习了一下 广播和多播(组播) 的知识.关于 单播和多播 的概念,可以用 QQ 中的一些例子来解释. 单播,就像 两个人聊QQ 一样,信息的接收和传递只在两个节点之间 ...

  5. UDP:rfc768/广播和多播/IGMP

    封装情况:

  6. netty的Udp单播、组播、广播实例+Java的Udp单播、组播、广播实例

    网络上缺乏netty的udp的单播.组播案例,经过一番学习总结之后终于把这两个案例调通,下面把这两个案例的代码放在这里分享一下. 首先推荐博文: http://colobu.com/2014/10/2 ...

  7. TCP/IP协议原理与应用笔记12:单播、多播和广播地址(目的地址)

    根据数据接收者的接收范围,将目的地址分为单播.多播.广播. 这里目的地址的划分主要针对的是 物理地址 和 IP地址,没有涉及到端口地址,因为主要针对标识通信节点的地址(物理地址 和 IP地址)而言,和 ...

  8. UDP单播和组播使用SO_REUSEADDR 测试结果

    UDP单播通信 一. 预置条件 A.B在同一台机器,网络中存在往A.B所在的机器的8888端口发送单播UDP数据 A:端口复用绑定在端口8888上 B:端口复用绑定在端口8888上操作步骤:(1)先启 ...

  9. iOS 利用Socket UDP协议广播机制的实现

    1.前言 什么是UDP协议广播机制? 举一个例. 比如在一群人群中,一个人要找张三,于是你向人群里大喊一声(广播):"谁是张三" 假设它是张三,它就会回应你.在网络中也是一样的. ...

随机推荐

  1. 《精通并发与Netty》学习笔记(15 - 详解NIO中Buffer之position,limit,capacity)

    一.前言熟悉NIO的人想必一定不会陌生buffer中position,limit,capacity这三个属性吧,之前在学习的时候遇到一个问题:就是当你先往缓冲区写入一部分数据,然后调用flip()方法 ...

  2. SQL查询表的第一条数据和最后一条数据

    方法一: 使用TOP SELECT TOP 1 * FROM user; SELECT TOP 1 * FROM user order by id desc; 方法二: 使用LIMIT SELECT  ...

  3. Java总复习内容

    StringBuffer定义时需要用正确的方式 例如: StringBuffer xxx = new StringBuffer("雯雯是猪"); 使用StringBuffer的连接 ...

  4. 自学电脑游戏第三天(Swing组件)

    Swing组件 1.按钮(Jbutton) 示例:选择用户所喜欢的城市. import java.awt.*; import java.awt.event.*; import javax.swing. ...

  5. bootstrap导航栏PC端移动端之不同样式

    在此之前,我先说我之所以要改变网站PC移动双端不同样式的原因. 首先我的网站用到了bootstrap响应式布局,这是我网站的PC端导航栏: 这是我网站的移动端导航栏,看着就难受: 我用谷歌浏览器F12 ...

  6. 图片水印工具类java

    关于jar包的导入我就不多说了,我会把引入的jar包显示出来,大家自行Google package com.net.util; import java.awt.AlphaComposite; impo ...

  7. Mybatis Plus带多条件的多表联合、分页、排序查询

    目录 一.现有表 student学生表: facultylist学院表: 二.同时满足以下需求: 1.多表联合查询出学院名字 2.可以带多条件查询 3.指定页码,页数据大小进行物理分页查询 三.解决步 ...

  8. work note

    eclipse git 察看历史 左边是提交的 import { NgModule } from '@angular/core'; import { IonicPageModule } from 'i ...

  9. review代码,需要做些什么???

    有一种习惯,叫看代码找问题:有另一种习惯,叫不看代码很不习惯. 这,矛盾,处处不在! review代码(code diff升级)到底可以做些什么?该做些什么? 1.整体代码风格是否贴切已有框架的设计风 ...

  10. 用JavaScript写一个简单的倒计时,可以应用在发送短信验证码的“59秒后重新发送验证短信”

    倒计时——从10倒数到0,点击按钮会还原倒计时 <body> <!-- 将textvalue值设为10,从10倒数 --> <input type="text& ...