转载

现代TCP/IP网络编程-UDP

UDP 的 connect()

  • 前方提到,如果使用的是 UDP 套接字进行通信的话,可以采取 connect 来进行优化,但是却不知原因。
  • 首先 UDP 的别称叫做 不可靠连接 , 也就是说它可以不需要对发送出去的数据负责任,在默认情况下这是对的,因为效率。
  • 但是如果一个 UDP 套接字端 需要与另一个端进行多于一次的通信的时候,就会出现性能问题:
    • 具体是: 连接两端通信 -> 发送数据 -> 断开连接 -> 连接两端通信 -> 发送数据 -> 断开连接 ......
    • 可以看出,需要重复的进行 连接和断开, 且这两个操作都是涉及 内核 操作,耗费的资源不可忽略
    • 所以在必要时对 UDP 套接字调用 connect ,是有必要的(并不硬性要求两端同时都要调用 connect )
    • 需要注意的是 TCP 套接字 同样需要调用(必须调用) connect ,虽然调用的函数接口一样,但是意义却是不相同的,前者是为了三次握手建立连接,而 UDP 却只是为了能够省去 不必要的断开连接 以及接收到 ICMP错误报文
  • ICMP 错误报文,指的是如果对端没办法接收到本端发送的信息的话,会返回一个错误,这个错误使用的就是 ICMP (ICMPv4和ICMPv6两种)
    • 如果 UDP 套接字通信时采用的是 未连接(unconnected) 的形式,那么在调用 sendto 接口之后,不管对端有没有收到信息,都会立即返回成功的信息,而即使对端没办法收到信息,且向本端发送了 ICMP 报文,我们也是无法检测到的。
    • 但是如果 UDP 套接字通信时采用的是 连接(connected) 的形式,那么就会接收到一个 EHOSTUNREACH 的错误,我们就能够捕捉到(这点与TCP的处理方式一样)。
  • 假设我们想要断开连接 或者 重新选择一个对端进行通信,也是可以的
    • 所需要做的也仅仅是在此调用一下 connect 接口函数
      struct sockaddr_storage unconnect; memset(&unconnect, 0, sizeof unconnect); unconnect.ss_family = AF_UNSPEC; /* 将 xxx_family 位置为 AF_UNSPEC 就表明要断开连接 */ connect(udp_sock, (struct sockaddr *)&unconnect, sizeof unconnect); /* 断开连接 */ 

注: 断开连接或者重新对套接字建连接是 UDP 才可以使用的,千万不要用在 TCP套接字上面!

  • TCP 这种面向连接的方式不同, UDP 不管是否是连接的(connected),它依旧是一种不可靠的传输方式,所以当它调用 connect 时,即使对端没有运行,这个函数也不会有任何错误,知道发送第一条信息时才能知道对端到底可不可达。
正文到此结束
Loading...