zoukankan      html  css  js  c++  java
  • UDP的坏处

    众所周知,UDP是一个面向无连接的协议。通信时不可靠的。
    这就会出现一些问题

    (1)数据报丢失

    因为是无连接,的所以可以用recvfrom和sendto来接收和发送消息,如果socket是阻塞的,那么当由于网络原因丢包了,那么发送和接收双方都面临无限期的阻塞。当然这个可以为客户端设置超时时间来解决。

    (2)验证收到的响应:

    因为是面向无连接的,所以,UDP的通信双方可能并不关心谁给它发了消息。接收方可能不会判断消息来源。A给你发个消息,B说收到了,你还以为A收到了。为了避免这种情况,可以通过保存recvfrom中的结构体,来校验下次发过来的消息是否出自同一人。

    (3)服务器未运行:

    客户端只是将数据发送出网卡,至于别人收没收到,根本不关心。有可能网络不同,有可能服务器没启动,但这些都不得而知,这显然是不行的。这个问题可以通过connect来连接UDP套接字实现。
    对UDP套接字调用connect,并不会向TCP那样产生三次握手,内核会校验对方是否存在,如果存在就记录地址和端口号。
    这样,再对UDP操作的时候,就可以直接使用read/write,而不必每次指定地址端口。收到的响应消息是谁的,也是一清二楚的。一般地情况下,只有客户端会去connect服务器,很少有服务端主动connect客户端的。
    当碰到以下两种情况时,可以对UDP套接字第二次调用Connect。①指定新的IP地址和端口;②断开套接字;当执行第二个功能时,可以把地址结构的地址族成员设置为AF_UNSEC。

    (4)UDP本身是缺乏流量控制的。

    UDP的缓冲区是有限的,收到的数据只有被读取后,才会释放它所占用的缓存。所以UDP平时也是能接多少是多少,多了的数据一律丢掉,服务端和客户端对此都可能不知情。这样当然并不好。所以一般情况下,可以用IO复用,比如说select,当UDP套接字发生变化时就及时通知处理进程读取数据。这样可以近可能的避免流量过大造成的数据丢失。

  • 相关阅读:
    关于 MySQL int tinyint 类型的那点事
    PHP日期、时间戳相关的小程序
    [leedcode 236] Lowest Common Ancestor of a Binary Tree
    [leedcode 235] Lowest Common Ancestor of a Binary Search Tree
    [leedcode 234] Palindrome Linked List
    [leedcode 233] Number of Digit One
    [leedcode 232] Implement Queue using Stacks
    [leedcode 231] Power of Two
    [leedcode 230] Kth Smallest Element in a BST
    [leedcode 229] Majority Element II
  • 原文地址:https://www.cnblogs.com/bugutian/p/5335535.html
Copyright © 2011-2022 走看看