UDP,全称 User Datagram Protocol,中文名称为用户数据报协议,主要用来支持那些需要在计算机之间传输数据的网络连接。
UDP 协议从问世至今已经被使用了很多年,虽然目前 UDP 协议的应用不如 TCP 协议广泛,但 UDP 依然是一种非常实用和可行的网络传输层协议。尤其是在一些实时性很强的应用场景中,比如网络游戏、视频会议等,UDP 协议的快速能力更具有独特的魅力。
UDP 是一种面向非连接的协议,面向非连接指的是在正式通信前不必与对方先建立连接,不管对方状态就直接发送数据。至于对方是否可以接收到这些数据,UDP 协议无法控制,所以说 UDP 是一种不可靠的协议。
UDP 协议适用于一次只传送少量数据、对可靠性要求不高的应用环境。
与前面介绍的 TCP 协议一样,UDP 协议直接位于 IP 协议之上。实际上,IP 协议属于 OSI 参考模型的网络层协议,而 UDP 协议和 TCP 协议都属于传输层协议。
因为 UDP 是面向非连接的协议,没有建立连接的过程,因此它的通信效率很高,但也正因为如此,它的可靠性不如 TCP 协议。
UDP 协议的主要作用是完成网络数据流和数据报之间的转换在信息的发送端,UDP 协议将网络数据流封装成数据报,然后将数据报发送出去;在信息的接收端,UDP 协议将数据报转换成实际数据内容。
可以认为 UDP 协议的 socket 类似于码头,数据报则类似于集装箱。码头的作用就是负责友送、接收集装箱,而 socket 的作用则是发送、接收数据报。因此,对于基于 UDP 协议的通信双方而言,没有所谓的客户端和服务器端的概念。
UDP 协议和 TCP 协议简单对比如下:
TCP 协议:可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。
UDP 协议:不可靠,差错控制开销较小,传输大小限制在 64 KB以下,不需要建立连接。
相比较 TCP,UDP 是一种不可靠的网络协议,它在通信实例的两端各建立一个 socket,但这两个 socket 之间并没有虚拟链路,它们只是发送、接收数据报的对象。
从专业的角度说,TCP的可靠保证,是它的三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。不过UDP的速度是TCP比不了的,而且UDP的反应速度更快,QQ就是用UDP协议传输的,>关键是recvfrom返回的客户端addrClient是不能作为服务器返回客户端的地址使用的,即在sendto中不能使用由recvfrom返回得到的客户端地址。 楼主将UDP通讯和TCP通讯搞混了,不过说实话这个是很正常的。当初我学的时候没一本书是把网络通信编程写清楚地,只能靠自己摸索。 socket可以理解为通信地址,它由协议,IP和端口组成。在UDP模式中,绑定的目的是要告诉 *** 作系统,当网卡从外部接收到数据包时, *** 作系统就知道应该把这个数据包交给哪个应用程序。 具体是这样的,网卡总是知道自己的IP是什么,因此网卡接收到网线中的数据包时,会提取数据包的包头,里面含有的IP如果是网卡自己的IP,它就会把该数据包交给 *** 作系统,如果不是就将该数据包丢弃,可以认为 *** 作系统不知道有该数据包。 *** 作系统接收到数据包后,会根据每个数据包包含的端口号,将该数据包发给不同的应用程序。 *** 作系统怎么会知道哪个端口号对应哪个应用程序呢?这个就是要求应用程序使用bind函数,将自己的端口号告诉 *** 作系统。因此,所谓的端口冲突就是指其他应用程序已经通过bind告诉了 *** 作系统该端口被它使用了,因此另外的应用程序就不能使用该端口了,即bind肯定失败! 所以,bind肯定是由接受数据包的应用程序使用的,这样的应用程序就是服务器应用程序,也可以看到我们需要为bind提供IP和端口号。并且,当初我还在疑惑为什么会有一个INADDR_ANY的IP指定,似乎bind根本不需要IP啊,只要端口就可以了。仔细一想才明白,因为一台主机可能会有2个网卡。因此,主机可能会有两个IP,这样bind这个函数允许我们自由指定需要绑定到哪块网卡上的特定端口。也可以不指定,通过INADDR_ANY由 *** 作系统为我们指定。譬如,13端口在第一块网卡中被占用了,我们就可以使用bind明确指定自己的应用程序接收来自第二块网卡13端口的数据包。 UDP编程中作为客户端发送数据时,是不需要指定自己的IP和端口的,因此无需使用bind绑定,直接在sendto指定服务器的IP和端口就可以了。但实际上发送数据时, *** 作系统还是需要使用客户端机器上的一个IP和端口号的,这个IP和端口号由 *** 作系统指派,譬如在 *** 作系统处理sendto时,它可以指派1005端口给UDP客户端,此时如果有另一个客户程序再使用bind注册该端口,就会失败了。但实际情况大家都知道,UDP数据包的发送是相当快的,这种冲突几乎不存在,因为数据包发送后,即数据包通过网卡发到了网线中, *** 作系统就认为发送成功了,该端口就会被 *** 作系统收回,标记“未使用”。 总结一下,UDP服务器需要占用一个IP和一个端口号,且是固定的,是在调用了bind函数成功后便确定下来了。UDP客户端也需要使用一个IP和一个端口号,它们都是随机的,这次发送可能是第一块网卡,第二次可能是第二块网卡,端口也如此。发送后,该端口就被 *** 作系统收回,因此客户端无法使用该端口接收来自服务器的数据包。 因此不能使用recvfrom的客户端的端口信息再调用sendto发送给客户端,因为客户端的电脑 *** 作系统根本不会讲该数据包交给客户端应用程序。 以上用比较容易理解的概念介绍了下,其实精确说的话,很多事情不是 *** 作系统做的,而是各种驱动程序完成的。具体怎么修改代码,楼主应该明白了吧,光改服务器端的代码,没用,客户端的代码也要改。这也是为什么UDP是不存在服务器,客户端之说的原因,因为任何一方给另一方发数据包,前提必须使另一方已经通过bind绑定了一个固定端口了。从专业的角度说,TCP的可靠保证,是它的三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。不过UDP的速度是TCP比不了的,而且UDP的反应速度更快,QQ就是用UDP协议传输的,>欢迎分享,转载请注明来源:内存溢出
评论列表(0条)