03丨套接字和地址:像电话和电话号码一样理解它们
03丨套接字和地址:像电话和电话号码一样理解它们
讲述:冯永吉
时长11:00大小10.07M
socket 到底是什么?
更好地理解 socket:一个更直观的解释
socket 的发展历史
套接字地址格式
通用套接字地址格式
IPv4 套接字格式地址
IPv6 套接字地址格式
几种套接字地址格式比较
总结
思考题
赞 38
提建议
精选留言(81)
- 业余爱好者置顶2019-08-07unix系统有一种一统天下的简洁之美:一切皆文件,socket也是文件。 1.像sock_addr的结构体里描述的那样,几种套接字都要有地址族和地址两个字段。这容易理解,你要与外部通信,肯定要至少告诉计算机对方的地址和使用的是哪一种地址。与远程计算机的通信还需要一个端口号。而本地socket的不同之处在于不需要端口号,那么就有了问题2; 2.本地socket本质上是在访问本地的文件系统,所以自然不需要端口。远程socket是直接将一段字节流发送到远程计算机的一个进程,而远程计算机可能同时有多个进程在监听,所以用端口号标定要发给哪一个进程。展开
作者回复: 回答的很好,给你点赞
共 8 条评论215 - 奔跑的码仔2019-08-10个人感觉“Pv4、IPv6、本地套接字格式以及通用地址套接字”的思想类似于OOP中的继承和多态。通用套接子为抽象类,其他套接字实现该抽象类。这样,可以定义基于通用套接字这个抽象类各种通用接口,其他套接字,也就是具体类,可以完全复用这套接口,即,实现了socket编程的多态!
作者回复: 这个理解我给满分。
共 7 条评论50 - conanforever222019-08-071. 我觉得这样设计的目的是为了给用户提供一个统一的接口, 不用每个地址族成员都增加个函数原型; 只用通过sockaddr.sa_family来确定具体是什么类型的地址, 有点工厂模式的意思; 如果是C++的话就可以用函数重载来实现了 2. socket主要还是为了进程间通信, 本地套接字主要用于本地IPC, 网络套接字用于跨机器通信; 如果把socket抽象成文件的话, 通信进程双方需要能够根据一个唯一的fd来找到彼此, 跨机器的话可以用端口, 本地的话直接用文件inode就可以了展开
作者回复: 你的理解很到位,工厂模式我倒是没有仔细想过,有点独辟蹊径
共 2 条评论41 - nil2019-08-07第一问,通用网络地址结构是所有具体地址结构的抽象,有了统一可以操作的地址结构,那么就可以涉及一套统一的接口,简化了接口设计。通用地址结构中第一个字段表明了地址的类型,后面的数据可以通过具体类型解析出来,一般只有将具体地址类型的指针强制转化成通用类型,这样操作才不会造成内存越界。 第二问,本地socket基于文件操作的,因此只需要根据文件路径便可区分,不需要使用端口的概念。展开
作者回复: 正解
共 3 条评论28 - xcoder2019-08-07老师能讲下关于WebSocket、Http和socket之间的联系吗?
作者回复: Http是应用层协议,是基于Tcp socket的实现,websocket是http的增强,利用了Tcp双向的特性,增强了服务器端到客户端的传输能力 以前客户端是需要不断通过轮询来从服务端得到信息,使用websocket以后就可以服务端直接推送信息到客户端
共 4 条评论27 - Mark2019-09-12AF_xxx 这样的值来初始化 socket 地址,用 PF_xxx 这样的值来初始化 socket。 请教老师,这一句具体怎么理解?
作者回复: //socket地址初始化 servaddr.sin_family = AF_INET; //socket初始化 listenfd = socket(PF_INET, SOCK_STREAM, 0);
共 4 条评论23 - Sweety2019-08-07打卡。感觉评论区的人都好厉害。
作者回复: 我也觉得
12 - 衬衫的价格是19美元2019-09-30通用地址格式sockaddr长度只有16字节,实际存放ip地址的只有14字节,怎么存的下ip6的地址的?这里还是不太明白
作者回复: 实际上这个通用地址格式,你可以理解为void *,我在文章里也指出了,设计套接字的时候,还没有提供void *类型的指针,所以用通用地址格式来表示。 在IPV6地址时,实际上传入的还是28个字节的数据,通用地址只是一个"参数类型",在函数处理时,实际上可以根据AF_xxx的类型来判断,真正的地址是IPV6,那么是28个字节的数据需要被使用,而不是16个字节。
共 5 条评论10 - Linuxer2019-08-072字节表示地址族很富裕,知道地址族,基本确定地址结构,通用地址结构,能够很好区分这两部分,一个字符数组就能知道每一种地址结构的起始地址,高明
作者回复: 回答的也很高明
共 2 条评论8 - 钱2019-11-19评论区都是高手,不过只输入不输出,脑袋是容不下的。所以,先不管对错,也记一下自己的思考。 感觉电脑一多,脑袋就乱,我来简化一下 如果世界上只有一台,那网络通信也就不需要了,不过单独的这台电脑上的文件,只要知道路径应该是能访问的,所以,不需要什么IP和端口 如果世界上只有两台电脑,并且每台电脑上可以运行多个进程,如果这两台电脑上的两个进程间想通信,那就需要端口号了,否则定位不了唯一的进程 如果世界上只有三台电脑,并且每台电脑上可以运行多个进程,其中有两台电脑上的进程之间想通信,那么就需要有IP和端口号了,IP用于定位电脑,端口号用于定位进程 世界上只有三台电脑,其实可以扯三根网线,此时长链接也是很容易理解的,实际上现在世界上有上亿级的电脑都在互联网上,如果两两互联都通过专有的网线,那这网线的数量就是个天文数字,也不现实。此时,这个长链接是怎么维护的,有些线路必然会公用的,我有些想不明白,分时公用?还是有个特殊标志?或者线路本身就是无时无刻都在公用的?展开
作者回复: 长链接并不是一直占用的一条物理链路哦,它实际上只是分配了固定的资源,可以维护通信双方在一定时间内的"逻辑"链路。
共 5 条评论5 - (☆_☆)2019-08-07讲的太好了,越来越懂网络编程了
作者回复: 渐渐进入状态了
4 - Kean2019-10-12第一个问题,各个地址的模式一致,都是标志加数据的组织形式,这种模式有三个好处:一是方便,我们可以用头两个字节知道采用的地址族,进而进行对应的解析;其次是节省空间,不用按照最大长度来使用统一的长度;最后是灵活,各个地址可以自由定义数据部分。这种模式在很多框架里都有运用,比如redis源码里面就大量的用到了这个模式。第二个问题是文件没有端口可言,因为文件路径可以唯一标识文件资源3
- zhchnchn2019-08-07请问老师,实际编程中一般使用sockaddr_in,sockaddr_in6,sockaddr_un结构,那么通用套接字地址结构sockaddr的作用是什么?一般在什么场景下使用?
作者回复: 通用套接字就是所有函数的入口参数,用通用套接字就不需要为Tcp udp等各定义一组socket函数了,前面一位同学总结它为工厂模式,我认为挺到位的
3 - нáпの゛2020-08-141 通用地址的作用主要是为了充当通用的指针,使接口参数传入统一,具体使用时强制转换为实际地址类型来解析。 2 感觉端口就是文件路径索引的意思,设计者为了方便使用搞了端口的概念。我的理解是走文件系统(本地套接字)就不需要端口,如果走协议栈就需要端口,远端通信只能走协议栈,所以必须要端口号。
作者回复: 赞
2 - youngitachi2019-09-19这个是上次的问题: 老师好,对于第二个问题我有个疑问。 假如知道远程服务器socket的路径,从理论上来讲,是否可以不需要端口号了呢? 接下来是第二次提问: 可能我没描述清楚,其实我的意思是这样的:我理解的是,指定了端口,就知道了和那个进程通信嘛,那么如果假设知道了远程主机的socket的路径了,是否可以不需要端口就能通信? 就假设我们要自己设计并实现个传输层协议,这个协议里我不指定端口,而是指定双方通信进程在主机上的路径,这样的协议是否可以满足通信呢?展开
作者回复: 如果你说你自己想设计一个跨主机,通过路径方式的通信机制呢,我觉得理论是可行的。当我们这里还是讨论现有的TCP/IP实现。
2 - 吴文敏2019-08-28老师可以讲一下grpc和rest的区别有哪些吗?为什么都说grpc比rest好、性能更高?
作者回复: grpc是一个基于tcp的协议,定义了序列化和反序列化的格式,而rest是基于http协议的,可能传递同样的信息,grpc的报文比http更优化,另外就是常用的rest都不是一个长连接,每次都有建连的成本, grpc可以做到长连。
2 - pyhhou2019-08-09请教老师一下,看完文章,了解了 socket 在 “客户端-浏览器” 这样一个架构中扮演的角色,但是我对 socket 的概念还不是特别理解,不太明白的是,socket 的定义到底是什么?它是和 HTTP、TCP 类似的约定俗成的协议吗?还是说是一个文件,亦或是一段程序代码,里面记录了一些当前网络通信中涉及到的协议、地址、端口号以及其他的一些必要参数?
作者回复: socket是一个抽象概念,你写代码的时候需要和socket打交道,后面代码片段看到就会明白的。
共 2 条评论2 - 刘明2019-08-07通用地址格式sockaddr为什么设计成16字节这么长,而不是与最长的sockaddr_un一样长呢?
作者回复: 这个通用地址格式的一个主要目的就是强制将IPV4、IPV6地址转换为统一格式,实现程序可以根据Family字段读取后面的值,所以它不需要设计那么长,只需要和最短的IPV4保持一致即可。
共 2 条评论2 - 简单猫2021-05-10从文章来理解 且不去看资料。 1.既然是解决进程间的通信问题。就可以想到很多问题,不同机器,可以通过字节流在网络上传输数据 并通过协定好的格式进行序列化反序列化。 2.本机则可以通过内存字节流(只要约定好内存地址就好,内存实现)。 本地还可以通过文件来存储,双方通过已知的路径名 来读写文件实现进程的数据交换(我认为这个是硬盘实现) 所谓套接字原理本身并不复杂,复杂的它的规范和实现原理展开
作者回复: 同意
1 - 郑祖煌2020-06-121. IPv4、IPv6、本地套接字格式 他们都要监听对应的端口,并且绑定对应的地址 2.本地套接字格式是通过读写本机的文件来进行相互通信的。1