原文地址:http://c.biancheng.net/view/2125.html

  • 上一节《套接字有哪些类型》提到,流格式套接字(Stream Sockets)就是“面向连接的套接字”,它基于 TCP 协议;数据报格式套接字(Datagram Sockets)就是“无连接的套接字”,它基于 UDP 协议。
    这给大家造成一种印象,面向连接就是可靠的通信,无连接就是不可靠的通信,实际情况是这样吗?
    另外,不管是哪种数据传输方式,都得通过整个 Internet 网络的物理线路将数据传输过去,从这个层面理解,所有的 socket 都是有物理连接的呀,为什么还有无连接的 socket 呢?
    本节就来给大家解开种种谜团,加深大家对数据传输方式的认识。
    从字面上理解,面向连接好像有一条管道,它连接发送端和接收端,数据包都通过这条管道来传输。当然,两台计算机在通信之前必须先搭建好管道。
    无连接好像没头苍蝇乱撞,数据包从发送端到接收端并没有固定的线路,爱怎么走就怎么走,只要能到达就行。每个数据包都比较自私,不和别人分享自己的线路,但是,大家最终都能殊途同归,到达接收端。
    这样理解没错,但是我相信这还不够深入,大家还是感觉云里雾里,没有看到本质。好,接下来就是见证奇迹的时刻,我会用实例给大家演示!
    § 2.面向连接和无连接的套接字到底有什么区别? - 图1
    上图是一个简化的互联网模型,H1 ~ H6 表示计算机,A~E 表示路由器,发送端发送的数据必须经过路由器的转发才能到达接收端。
    假设 H1 要发送若干个数据包给 H6,那么有多条路径可以选择,比如:

    • 路径①:H1 —> A —> C —> E —> H6
    • 路径②:H1 —> A —> B —> E —> H6
    • 路径③:H1 —> A —> B —> D —> E —> H6
    • 路径④:H1 —> A —> B —> C —> E —> H6
    • 路径⑤:H1 —> A —> C —> B —> D —> E —> H6

      数据包的传输路径是路由器根据算法来计算出来的,算法会考虑很多因素,比如网络的拥堵状况、下一个路由器是否忙碌等。

无连接的套接字

  • 第一个数据包选择了一条比较长的路径(比如路径 ⑤),第三个数据包选择了一条比较短的路径(比如路径 ①),虽然第一个数据包很早就出发了,但是走的路比较远,最终还是晚于第三个数据包达到。
  • 第一个数据包选择了一条比较短的路径(比如路径 ①),第三个数据包选择了一条比较长的路径(比如路径 ⑤),按理说第一个数据包应该先到达,但是非常不幸,第一个数据包走的路比较拥堵,这条路上的数据量非常大,路由器处理得很慢,所以它还是晚于第三个数据包达到了。

  • 第一个数据包选择了路径 ①,但是路由器 C 突然断电了,那它就到不了 H6 了。

  • 第三个数据包选择了路径 ②,虽然路不远,但是太拥堵,以至于它等待的时间太长,路由器把它丢弃了。

面向连接的套接字

§ 2.面向连接和无连接的套接字到底有什么区别? - 图2

发送端发送一个数据包,如何得到接收端的确认呢?很简单,为每一个数据包分配一个 ID,接收端接收到数据包以后,再给发送端返回一个数据包,告诉发送端我接收到了 ID 为 xxx 的数据包。

总结

  • 无连接套接字传输效率高,但是不可靠,有丢失数据包、捣乱数据的风险;
  • 有连接套接字非常可靠,万无一失,但是传输效率低,耗费资源多。