第 5 天: 以农村故事说说我对 socket 的理解

在上次内容 (第3天:HTTP 之客户端与服务端 )的留言中,我们一起讨论了什么是 socket ,每个人对它理解的都不一样,这一点非常出乎我的意料。我从留言中摘取了一小部分:

.: socket 的作用就和它的中文翻译一样:插座,方便使用各种电器,当然你不用插座直接接零线火线也行……

真有意思:socket套接字,用于建立端与端之间的通信连接,server端和客户端都需要建立socket,之后才能进行tcp/ip通信,具体socket是什么,不清楚。

白开水 :socket 是一条线的两个插头,一个插在客户端,一个插在服务端,通过这条线实现两端的直连,达到长连接的效果。

奔流河:进程间通信如同文件的读写,都符合open—write/read—close模式。而socket就是其中一种通信方式的抽象,可以理解为一种文件描述符,用于不同进程间的通信!在传输层面有基于TCP的socket,自然也有基于UDP的socket,当然还有更简单的基于http的websocket……

樹葉:套接字,实现跨机器的进程间的通信。


上面的同学回答都很有意思,无论对与错,我们先看下百度百科关于 socket 的定义:

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。-- 百度百科。

看完上面关于 socket 的描述,我不是很懂,其原因我觉得是因为我脑海里无法想象到它的样貌。想要理解一个知识如果能够实实在在地感受它的存在,理解起来自然而然就比较轻松。比如什么是苹果,我们脑子里会浮现出苹果的样子。同样,如果你光知道 socket 的概念却不知道它的样貌,就很难理解它。所以,在理解 socket 之前,有必要先了解它出现的背景。

下面内容进入故事情节:

想象一下同一台电脑进程之间是如何通信的?谈到进程通信有人可能比较陌生。那我们就以一个故事开始今天的分享吧。不知道你们有没有去过农村,北方的农村结构大致是这样的,一个村子里大约有 30 户人家,每家都有自己独立的房子和院子,各自的居住空间互不侵犯。我们可以把“村子”比作是一个操作系统,把“每户人家”比做进程,「进程间通信」就是各户人家的正常交流,比如张三家没盐了可以到邻居家借点回来。进程也是这样的,有时候它也要到别的进程中获取一些资源。光计算机自己进程之间同学还容易,但是一旦踏足于网络,一切变得复杂了。

以前村与村之间的交流很少,直到公路建设起来后,各家都买了小汽车,村与村之间的交流逐渐在增多。「公路」就好比我们的光缆,用来连接不同的计算机进行数据传输,「小汽车」就好比数据包,它在光缆上进行传输。

一天张三碰到走在路上的王五问到:“你要去哪?”。王五回答到:“到隔壁村买瓶二锅头”。注意对话中的“隔壁村”,以前村子是没名字的,只能通过类似与“隔壁村”、“山后面那个村”等字样来描述指定的位置。随着公路在逐渐扩建,连接起来的村子越来越多,光靠模糊的描述已经不能满足人们日常的交流了。人们想到了一个好办法,给每个村起个名字,共同制度一个标准。以后,王五就可以这样回答:“到段山洼(村名)村买瓶二锅头”。村名能够标识一个村子。但是后来小卖部(超市)越来越多,为了区分不同的小卖部,给小卖部也起了名字。以后,王五就可以这样回答:“到段山洼(村名)村小张(小卖部名)家买瓶二锅头”。

同样,连接到网络中的计算机也非常多,为了满足不同网络中的计算机之间进程的通信,socket 就出现了,它的出现解决了计算机在网络中的通信问题。它以「 ip + 端口」的形式来标记一个进程。如果想访问某台计算机中的某个程序,比如它 ip 是 127.0.0.1,端口为 8888,那么就可以通过 127.0.0.1:8888 这样的方式来访问。“段山洼的小张家”可以理解为某台计算机中的某个进程,用 socket 来说“段山洼”是ip地址,小张家是端口号。

人们在通往各村之间可以选择多种交通工具。张三家没钱,只能买辆自行车来骑,但他比较靠谱,交给他办的事100%能给你搞定;王五这家伙这几年做生意赚钱了,买了辆奥迪,每天开的挺潇洒,但为人丢三落四,交给他办事很快,但是不放心,说不定让他送个东西半路就丢了。我们称“张三”这条线路就叫 TCP 连接,而“王五”这条路线就叫 UDP 连接。它们的连接方式都是通过 socket 建立的连接,也就是村与村之间的连接靠的是 socket ,具体连接到每户人家靠的是端口号,它是一个连接标准,具体连接的靠不靠谱,关键看“人”靠不靠谱。

socket 可以有多种,比如流式,它使用的是 TCP 协议实现的;数据报格式,它使用的是 UDP 实现的。

上节内容中,我们使用了 Socket,不知道你是否留意过这段代码:

let net = require('net');// 创建一个 Socket 连接let client = net.Socket();
// 连接 TCP Server 端client.connect('8888', '127.0.0.1', function () { Log('have connected to server'); sendMsg();});
// 收到 Server 端发来的消息client.on('data', function (data) { Log(data.toString()); setTimeout(() => { sendMsg(); }, 1000);});

socket 通信是双向的,客户端可以给server端主动发消息,server 端也可以给客户端主动发消息,这一点不想 HTTP 协议,只能客户端主动发起请求。这是我对 socket 的一个理解,如果有不妥的地方,欢迎留言表明你的观点。到目前为止,网络相关的内容从 HTTP 追踪到 socket,接下来我们会看看 HTTP 协议是如何实现的。大家加油,记得打卡。


推荐阅读:
第4天:数据传输之 TCP ,聊天室实践(含视频)
第3天:HTTP 之客户端与服务端
https://tools.ietf.org/html/rfc3493.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值