十、Socket之UDP编程
UDP基础知识
UDP(User Datagram Protocol,用户数据报协议)是一个简单的、面向数据报的无连接协议,提供了快速但不一定可靠的传输服务。
UDP与TCP相比主要有以下区别。
1.UDP速度比TCP快
由于UDP不需要先与对方建立连接,也不需要传输确认,因此其数据传输速度比TCP快得多。
2.UDP有消息边界
使用UDP不需要考虑消息边界问题,使用上比TCP简单
3.UDP可以一对多传输
利用UDP可以使用广播或组播的方式同时向子网上的所有客户发送信息。这一点也比TCP方便。
4.UDP可靠性不如TCP
与TCP不同,UDP并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP称为不可靠的传输协议。
5.UDP不像TCP那样能保证有序传输
UDP不能确保数据的发送和接收顺序。对于突发性的数据报,有可能会乱序。事实上,UDP的这种乱序性基本上很少出现,通常只会在网络非常拥挤的情况下才有可能发生
UDP应用编程技术
UdpClient类
UdpClient类提供了发送和接收无连接的UDP数据报的方便的方法。封装了底层的套接字,并分别提供了对套接字进一步封装后的同步和异步操作的方法,降低了UDP应用编程的难度。 与TCP协议有TcpListener类和TcpClient类不同,UDP协议只有UdpClient类,这是因为UDP协议是无连接的协议,所以只需要一种Socket。
创建UdpClient的四种方式:
//1、自动分配合适的本地IPv4地址,并将基础socket与指定的本地端口号绑定。例如:
UdpClient udpClient = new UdpClient();//表示让系统自动为其分配一个合适的端口号 //2、与包含本地IP地址和端口号的IPEndPoint实例绑定。例如:
IPEndPoint iep = new IPEndPoint(IPAddress.Any, );
UdpClient udpClient = new UdpClient(iep); //3、自动分配合适的本地IP地址和端口号,用于收发数据,并使用hostname和port参数建立默认远程主机。例如:
UdpClient udpClient = new UdpClient("192.168.1.100", ); //4、自动分配合适的本地IPv4地址和端口号,但是该构造函数不执行套接字绑定。如果使用这种构造函数,在发送数据报之前,必须先调用Connect方法,且只能将数据报发送到Connect方法建立的远程主机。例如:
UdpClient udpClient = new UdpClient();
//指定默认远程主机和端口号
udpClient.Connect("192.168.1.100", );
Byte[] sendBytes = Encoding.Unicode.GetBytes("你好!");
//发送给默认远程主机
udpClient.Send(sendBytes, sendBytes.Length);
同步发送和接收数据
编写基于UDP的应用程序时,关键在于如何实现数据的发送和接收。由于UDP不需要建立连接,因此可以在任何时候直接向网络中的任意主机发送UDP数据。在同步阻塞方式下,可以使用UdpClient对象的Send方法和Receive方法。
Send:可直接将数据发送到远程主机,并返回发送数据的长度,Send方法发送数据的类型为byte数组。
Receive:能够在指定的本地IP地址和端口上接收数据,该方法带一个引用类型的IPEndPoint实例,并将接收到的数据作为byte数组返回。
发送数据:
UdpClient myUdpClient = new UdpClient();
try
{
IPEndPoint iep = new IPEndPoint(ip, port);
byte[] bytes = System.Text.Encoding.Unicode.GetBytes("你好!");
//UdpClient.Send (Byte[], Int32, IPEndPoint)
//Byte[]:待发送到远程主机的数据
//Int32: 待发送到远程主机的数据长度
//IPEndPoint :远程主机端点,包含了应用程序连接到主 机上的服务所需的IP地址和端口信息。
myUdpClient.Send(bytes, bytes.Length, iep);
}
catch (Exception err)
{
MessageBox.Show(err.Message, "发送失败");
}
接收数据:
UdpClient udpClient = new UdpClient(IPAddress.Parse("192.168.1.100"), );
//IPAddress.Any表示对方的IP地址可以是任何IP地址
//0表示对方的端口号可以是任何端口号。
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, );
try
{
Byte[] receiveBytes = udpClient.Receive(ref remoteIpEndPoint);//表示发送方的IP地址和端口号
string receiveData = Encoding.Unicode.GetString(receiveBytes);
Console.WriteLine("接收到信息:" + receiveData);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
异步发送和接收数据
对于UdpClient对象的每个同步方法,都有与之对应的异步BeginSend和EndSend方法。
发送数据:
UdpClient sendUdpClient = new UdpClient();
IPAddress remoteIP;
if (IPAddress.TryParse(textBoxRemoteIP.Text, out remoteIP) == false)
{
MessageBox.Show("远程IP格式不正确");
return;
}
iep = new IPEndPoint(remoteIP, port);
sendMessage = textBoxSend.Text;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sendMessage);
try
{
//异步发送数据
IAsyncResult ar=
sendUdpClient.BeginSend(bytes, bytes.Length, iep, null, sendUdpClient); textBoxSend.Clear();
textBoxSend.Focus();
}
catch (Exception err)
{
MessageBox.Show(err.Message, "发送失败");
}
接受数据:
//在本机指定的端口接收
UdpState udpState = new UdpState();
udpState.IpEndPoint = null;
udpState.MyudpClient = receiveClient;
//接收从远程主机发送过来的信息;
IAsyncResult ar = udpState.MyudpClient.BeginReceive(null, udpState);
ar.AsyncWaitHandle.WaitOne();
利用UDP协议进行广播和组播
TCP通信采用一对一的通信模式。日常生活中的网络会议通知、广告、网络信息公告等功能,需要采用UDP实现一对多的群发功能。
通过Internet实现群发功能的形式有两种:
(1)利用广播向子网中的所有客户发送消息,比如各类通知、单位公告、集体活动日程安排等;
(2)利用组播向Internet网上不同的子网发送消息,比如集团向其所属的公司或用户子网发布信息公告等。
组播和广播的区别:
(1)本地广播无法通过路由器,广播只是限于本网段内,遇到路由器则止。同网段内其他在指定端口侦听的程序都能收到该包都需要一个数据copy。组播没有这个限制,只要加入组就能收到数据包。
(2)由于广播是向某个子网中的所有计算机用户发送消息,没有目的性,会增加网络传输负担,而且资源消耗较高。组播将消息发送到加入指定组播组的计算机中,组播组是开放的,每台计算机都可以通过程序随时加入到组播组中,也可以随时离开,因此减少了不必要的网络传输负担。
加入和退出组播组
组播组:是分享一个组播地址的一组设备。任何发送到组播地址的消息都会被发送到组内的所有成员设备上。 组可以是永久的,也可以是临时的。大多数组播组是临时的,仅在有成员的时候才存在。
组播地址:组播地址是范围在224.0.0.0到239.255.255.255的D类IP地址。 IP组播使用特殊的IP地址范围来表示不同的组播组。 用户创建一个新的组播组时只需从地址范围内选出一个地址,然后为这个地址构造一个对象,就可以开始发送消息了。
加入组播组
//创建UdpClient的实例并设置使用的本地端口号
UdpClient udpClient = new UdpClient();
udpClient.JoinMulticastGroup(IPAddress.Parse("224.100.0.1"));
//或则
UdpClient udpClient = new UdpClient();
udpClient.JoinMulticastGroup(IPAddress.Parse("224.100.0.1"), );//其中50为TTL值。
//生存周期:TTL
//使用组播时,应注意的是TTL(Time To Live,生存周期)值
//的设置。TTL值是允许路由器转发的最大数目,当达到这个
//最大值时,数据包就会被丢弃。如果使用默认值(默认值为
//1),则只能在子网中发送。可以通过UdpClient对象的Ttl属
//性直接设置TTL值,例如:
UdpClient myUdpClient = new UdpClient();
myUdpClient. TTL = ;
//该语句设置TTL值为50,即最多允许50次路由器转发。
退出组播组
//利用UdpClient的DropMulticastGroup方法,可以退出组播组。参数中指出要退出的多路广播组的IPAddress实例。
//UdpClient从组中收回之后,将不能再接收发送到该组的数据报。
//例如:
udpClient.DropMulticastGroup(IPAddress.Parse("224.100.0.1"));
利用组播实现群发功能
1、广播的通信模式虽然能够实现一对多的通信需要,但是,由于广播是向子网中的所有计算机用户发送消息,没有目的性,不但增加了网络传输负担,而且资源消耗较高。
2、组播也叫多路广播。所谓组播是将消息从一台计算机发送到本网或全网内选择的计算机子集上,即发送到那些加入指定组播组的计算机上。
十、Socket之UDP编程的更多相关文章
- 【Socket编程】通过Socket实现UDP编程
通过Socket实现UDP编程 UDP通信: 1.UDP协议(用户数据报协议)是无连接.不可靠.无序的. 2.UDP协议以数据报作为数据传输的载体. 3.使用UDP进行数据传输时,首先需要将要传输的数 ...
- python网络-Socket之udp编程(24)
一.udp简介 udp --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地. udp在 ...
- 【LINUX/UNIX网络编程】之使用SOCKET进行UDP编程
先看任务需求: 实验二 UDP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本UDP通讯,实现服务器与客户端的文件传送 [实验学时] 4学时 [实验内容] ...
- java socket 之UDP编程
一.概念 在TCP的所有操作中都必须建立可靠的连接,这样一来肯定会浪费大量的系统性能,为了减少这种开销,在网络中又提供了另外的一种传输协议——UDP,不可靠的连接(这种协议在各种聊天工具中被广泛使用) ...
- 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤
福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 Java全栈大联盟 ...
- Socket网络编程-UDP编程
Socket网络编程-UDP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.UDP编程概述 1>.UDP服务端编程流程 创建socket对象.socket.SOCK_ ...
- Socket编程实践(12) --UDP编程基础
UDP特点 无连接,面向数据报(基于消息,不会粘包)的传输数据服务; 不可靠(可能会丢包, 乱序, 反复), 但因此普通情况下UDP更加高效; UDP客户/服务器模型 UDP-API使用 #inclu ...
- JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
JAVA之旅(三十二)--JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用 GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例, ...
- 五十六、linux 编程——UDP 编程模型
56.1 UDP 编程模型 56.1.1 编程模型 UDP 协议称为用户数据报文协议,可靠性比 TCP 低,但执行效率高 56.1.2 API (1)发送数据 函数参数: sockfs:套接字文件描述 ...
随机推荐
- 移动端web页面使用position:fixed问题
在做移动端项目时,碰到一个很纠结的问题,头部固定的问题,一开始使用fixed,发现一系列的问题, 问题1:footer输入框 focus 状态,footer 被居中,而不是吸附在软键盘上部. 测试环境 ...
- 【js】获得项目路径
var curWwwPath=window.document.location.href; //获取主机地址之后的目录,如: uimcardprj/share/meun.jsp var pathNam ...
- disabled
http://blog.csdn.net/dinglang_2009/article/details/6974887 如果把页面viewstate设为disabled 那么 ispost就一直为fal ...
- Ubuntu 12.04 安装Scrapy爬虫框架
转自:http://www.cnblogs.com/HelloPython/ 亲测有效 根据Scrapy安装指南(http://doc.scrapy.org/en/latest/intro/insta ...
- js特效第九天
offset家族(获取元素尺寸) offsetWidth得到对象的宽度,自己的,与他人无关 offsetWidth = width+border+padding,不包含margin offsetHei ...
- Ajax解决缓存的5种方法
原文:http://www.ido321.com/129.html 1.在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“If-Modified-Since”,”0″ ...
- Mysql engine
MySQL engine.type类型的区别:
- Mac java环境配置
进入命令行 cd ~ touch .bash_profile vi .bash_profile 输入内容jdk变量配置内容: export JAVA_HOME=/Library/Java/JavaVi ...
- Solution for Latex error: "Cannot determine size of graphic"
I'm trying to include graphics in my Latex-file, which I compiled with latex+dvipdf on OS X. Latex h ...
- openstack api
1,Identity service generates authentication tokens that permit access to the openstack service REST ...