套接字有哪些类型?socket有哪些类型?

这个世界上有很多种套接字(socket),比如 DARPA Internet 地址(Internet 套接字)、本地节点的路径名(Unix套接字)、CCITT X.25地址(X.25 套接字)等。但本教程只讲第一种套接字——Internet 套接字,它是最具代表性的,也是最经典最常用的。以后我们提及套接字,指的都是 Internet 套接字。

根据数据的传输方式,可以将 Internet 套接字分成两种类型。通过 socket() 函数创建连接时,必须告诉它使用哪种数据传输方式。
Internet 套接字其实还有很多其它数据传输方式,但是我可不想吓到你,本教程只讲常用的两种。

流格式套接字(SOCK_STREAM)

流格式套接字(Stream Sockets)也叫“面向连接的套接字”,在代码中使用 SOCK_STREAM 表示。

SOCK_STREAM 是一种可靠的、双向的通信数据流,数据可以准确无误地到达另一台计算机,如果损坏或丢失,可以重新发送。
流格式套接字有自己的纠错机制,在此我们就不讨论了。
SOCK_STREAM 有以下几个特征:
  • 数据在传输过程中不会消失;
  • 数据是按照顺序传输的;
  • 数据的发送和接收不是同步的(有的教程也称“不存在数据边界”)。

可以将 SOCK_STREAM 比喻成一条传送带,只要传送带本身没有问题(不会断网),就能保证数据不丢失;同时,较晚传送的数据不会先到达,较早传送的数据不会晚到达,这就保证了数据是按照顺序传递的。

将面向连接的套接字比喻成传送带

为什么流格式套接字可以达到高质量的数据传输呢?这是因为它使用了 TCP 协议(The Transmission Control Protocol,传输控制协议),TCP 协议会控制你的数据按照顺序到达并且没有错误。

你也许见过 TCP,是因为你经常听说“TCP/IP”。TCP 用来确保数据的正确性,IP(Internet Protocol,网络协议)用来控制数据如何从源头到达目的地,也就是常说的“路由”。

那么,“数据的发送和接收不同步”该如何理解呢?

假设传送带传送的是水果,接收者需要凑齐 100 个后才能装袋,但是传送带可能把这 100 个水果分批传送,比如第一批传送 20 个,第二批传送 50 个,第三批传送 30 个。接收者不需要和传送带保持同步,只要根据自己的节奏来装袋即可,不用管传送带传送了几批,也不用每到一批就装袋一次,可以等到凑够了 100 个水果再装袋。

流格式套接字的内部有一个缓冲区(也就是字符数组),通过 socket 传输的数据将保存到这个缓冲区。接收端在收到数据后并不一定立即读取,只要数据不超过缓冲区的容量,接收端有可能在缓冲区被填满以后一次性地读取,也可能分成好几次读取。

也就是说,不管数据分几次传送过来,接收端只需要根据自己的要求读取,不用非得在数据到达时立即读取。传送端有自己的节奏,接收端也有自己的节奏,它们是不一致的。

流格式套接字有什么实际的应用场景吗?浏览器所使用的 http 协议就基于面向连接的套接字,因为必须要确保数据准确无误,否则加载的 HTML 将无法解析。

数据报格式套接字(SOCK_DGRAM)

数据报格式套接字(Datagram Sockets)也叫“无连接的套接字”,在代码中使用 SOCK_DGRAM 表示。

计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。

因为数据报套接字所做的校验工作少,所以在传输效率方面比流格式套接字要高。

可以将 SOCK_DGRAM 比喻成高速移动的摩托车快递,它有以下特征:
  • 强调快速传输而非传输顺序;
  • 传输的数据可能丢失也可能损毁;
  • 限制每次传输的数据大小;
  • 数据的发送和接收是同步的(有的教程也称“存在数据边界”)。

众所周知,速度是快递行业的生命。用摩托车发往同一地点的两件包裹无需保证顺序,只要以最快的速度交给客户就行。这种方式存在损坏或丢失的风险,而且包裹大小有一定限制。因此,想要传递大量包裹,就得分配发送。

将无连接套接字比喻成摩托车快递

另外,用两辆摩托车分别发送两件包裹,那么接收者也需要分两次接收,所以“数据的发送和接收是同步的”;换句话说,接收次数应该和发送次数相同。

总之,数据报套接字是一种不可靠的、不按顺序传递的、以追求速度为目的的套接字。

数据报套接字也使用 IP 协议作路由,但是它不使用 TCP 协议,而是使用 UDP 协议(User Datagram Protocol,用户数据报协议)。

QQ 视频聊天和语音聊天就使用 SOCK_DGRAM 来传输数据,因为首先要保证通信的效率,尽量减小延迟,而数据的正确性是次要的,即使丢失很小的一部分数据,视频和音频也可以正常解析,最多出现噪点或杂音,不会对通信质量有实质的影响。
注意:SOCK_DGRAM 没有想象中的糟糕,不会频繁的丢失数据,数据错误只是小概率事件。

推荐文章
jQuery before()和insertBefore()方法

本节教程介绍 before()方法和insertBefore()方法在元素外部的“前面”插入内容。 Pythonbefore()方法 在jQuery中,我们可以使用before()方法向所选元素外部

Java转换流:InputStreamReader和OutputStreamWriter

正常情况下,字节流可以对所有的数据进行操作,但是有些时候在处理一些文本时我们要用到字符流,比如,查看文本的中文时就是需要采用字符流更为方便。所以JavaIO流中提供了两种用于将字节流转换为字符流的转换

Java自增和自减运算符(++和--)

在对一个变量做加1或减1处理时,可以使用自增运算符++或自减运算--。++或--是单目运算符,放在操作数的前面或后面都是允许的。++与--的作用是使变量的值增1或减1。操作数必须是一个整型或浮点型变量

MySQL函数简介

MySQL函数是MySQL数据库提供的内部函数,这些内部函数可以帮助用户更加方便地处理表中的数据。函数就像预定的公式一样存放在数据库里,每个用户都可以调用已经存在的函数来完成某些功能。 提示:函数就

C++文件读写结构体详解

C++ constintNAME_SIZE=51,ADDR_SIZE=51,PHONE_SIZE=14; structInfo { charname[NAME_SIZE]; intage;

Unity 3D Scrollbar控件

Unity3DScrollbar(滚动条)控件可以垂直或水平放置,主要用于通过拖动滑块以改变目标的比例,如下图所示。 它最恰当的应用是用来将一个值变为指定百分比,最大值为1(100%),最小值为0(

.py是什么文件?

“.py”文件是python的脚本文件。Python在执行时,首先会将“.py”文件中的源代码编译成Python的bytecode(字节码),然后再由PythonVirtualMachine(Pyth

DOS系统是什么操作系统?

DOS系统是磁盘操作系统(DiskOperatingSystem),是早期个人计算机上的一类操作系统。从1981年MS-DOS1.0直到1995年MS-DOS6.22的15年间,DOS作为微软公司在个

载入内存,让程序运行起来

如果你的电脑上安装了QQ,你希望和好友聊天,会双击QQ图标,打开QQ软件,输入账号和密码,然后登录就可以了。 那么,QQ是怎么运行起来的呢? 首先,有一点你要明确,你安装的QQ软件是保存在硬盘中的

Hibernate default_entity_mode属性:指定默认实体表现模式

hibernate.default_entity_mode属性用于为由SessionFactory打开的所有Session指定默认的实体表现模式。 语法: hibernate.default_en

Java字节流的使用:字节输入/输出流、文件输入/输出流、字节数组输入/输出流

在本章的第一节《Java流的概念》中就提到InputStream是Java所有字节输入流类的父类,OutputStream是Java所有字节输出流类的父类,它们都是一个抽象类,因此继承它们的子类要重新

文件压缩zip格式和rar格式的区别是什么?

在现在最常见的压缩文件有zip、rar、7z三种,它们都有各自的优点和缺点。我们用一句话来概括一下:7z压缩率最高,RAR安全性高,ZIP使用范围广。文件压缩打包是最为常见的一种分享方式了,而众多的压

Go语言数据库(Database)相关操作

本节将对db/sql官方标准库作一些简单分析,并介绍一些应用比较广泛的开源ORM和SQLBuilder。并从企业级应用开发和公司架构的角度来分析哪种技术栈对于现代的企业级应用更为合适。 从datab

JSP PageContext.getErrorData()方法:返回包含错误信息的ErrorData对象

该方法返回一个包含错误信息的ErrorData对象。 语法: getErrorData() 返回值: 返回一个包含错误信息的ErrorData对象,如果不在错误页调用,返回的信息是无意义的。

Linux yum命令详解(查询、安装、升级和卸载软件包)

在《yum及其源配置》一节的基础上,本节学习如何使用yum命令实现查询、安装、升级和卸载RPM包。 yum查询命令 使用yum对软件包执行查询操作,常用命令可分为以下几种: yumlist:查询

TensorFlow多层感知机实现MINIST分类(详解版)

TensorFlow支持自动求导,可以使用TensorFlow优化器来计算和使用梯度。它使用梯度自动更新用变量定义的张量。本节将使用TensorFlow优化器来训练网络。 前面章节中,我们定义了层、

Linux入门培训视频教程(思成老师出品11集)

通过该视频,您将学到: 熟悉Linux操作系统,熟练掌握常用的基本命令(掌握Linux的基础知识、掌握Linux常用的基本命令); 能够比较熟练地使用C语言在Linux下编写程序; 培养出扎实

Django Model三种继承模型详解

在Django中每个Model都是一个Pyhton类,前文之前提到过Model继承自django.db.models.Model。通过类之间的继承Django会对自定义的Model自动添加了两个属性分

使用Eureka编写服务消费者

本节主要讲解如何使用Eureka编写服务消费者。 1)直接调用接口 创建服务消费者,消费我们刚刚编写的user/hello接口,同样需要先创建一个Maven项目eureka-client-artic

c/s架构是什么意思?

C/S(ClientServer)C/S架构是客户端/服务器体系结构,其中客户端依靠服务器来获取资源,C/S架构通过提供查询响应来减少网络流量。它可以分为客户机和服务器两层:第一层:在客户机系统上结合