欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > socket

socket

2025/2/24 13:29:55 来源:https://blog.csdn.net/weixin_50809457/article/details/143863921  浏览:    关键词:socket

文章目录

    • 跨网络传输
    • 网络通信的基本脉络示意图
    • 总结
    • 命令ifconfig
  • 网络编程套接字
    • 端口号
    • 认识端口号
      • 端口号 vs 进程pid
    • 网络字节序
    • 套接字编程的种类

在这里插入图片描述
这是局域网,有很多主机

跨网络传输

跨网络传输,左边和右边其实不是一台主机而已,而是像上面局域网有很多主机
在这里插入图片描述
跨网络传输我们该怎么做?
问题是我怎么知道我要把数据跨网络交给目标主机呢?
这里牵扯到新概念
IP地址
IP地址能标识某一台主机 在全网中的唯一性
那MAC地址能不能保证呢?也可以但是它只是应用于局域网保证唯一性就可以了。
IP地址是什么?
为什么要有?
IP VS MAC地址 为什么要有这两货?有什么区别?

讲个生活经验
我们从辽宁出发,要去云南旅游
从哪里,到哪去 ----- 一直是不变的
上一站从哪里来,下一站去哪里 ------ 会一直变化,变化的依据是“”我要去哪里“”
在这里插入图片描述

唐僧 从东土大唐 出发 去西天取经
如果他到了女儿国,问女儿国国王我要去西天 下一站该怎么走?
女儿国国王就会问他 你从哪里来的?我从东土大唐来。
你上一站从哪里来?我从车迟国来。哦那你下一站应该去西天最近的火焰山了。
从哪来,到哪去,这套地址一直不变。我们把它称为IP地址。
上一站,和下一站代表MAC地址。但是上面的在同一个局域网中还可能感觉不出来。
现在为什么要有对应的IP地址?
他可以指导我们进行路径规划。
IP地址 是什么?
互联网支持主流IPV4,采用4字节,32比特位表示的一个整数,他最终可以书写为192.168.1.1类似风格对应的信息 称为IP地址。
目前说就直说公网IP,他可以标识互联网中特定主机的唯一性。
有了IP地址就可以根据目的IP来进行路径规划方便报文进行转发。

跨网络传输流程
在这里插入图片描述
网路通信首先要解决的是能走到下一跳主机,就像你从辽宁到云南,你得先能跳出辽宁省。
但是目前来说左边C端局域网里有很多主机,就是左下角的各种方块,你怎么知道下一跳要给路由器?
根据目的主机IP来判断目标主机 和 发送端主机不在同一个子网,则报文下一跳要给路由器。
我们凭什么要把数据交给路由器,是因为目标主机和发送主机不在同一网段。

在图中C端,把数据交给route路由器。本质:不就是局域网通信嘛。
因为路由器也是局域网中的一个设备
在这里插入图片描述
从此底层具体以太网 OR 令牌环网 在整个网络中底层的差异就完全被屏蔽了。
因为路由器会帮我们重新解包并重新封装,因为路由器要横跨两个网络,所以他必须有以太网也有令牌环网的驱动,所以进来去掉报头,出去再重新封装MAC令牌环的报头。

过程中发现,从IP层往上的所有协议可以做成完全一样,底层协议可以有很大差异,但无所谓,正因为IP的存在,所以IP协议屏蔽了底层网络的差异化。
靠的就是工作在IP层的路由器!

所以IP实现了全球主机的软件虚拟层,一切皆是IP报文!
这就很像我们OS中struct file的一切皆文件,这就是软件层状结构的优越性。

手机也是无限LAN,你可以底层局域网协议和我以太网不一样,只要路由器具有脱衣服,穿衣服的能力,解包和重新封装新的局域网协议报头的能力,我们是一样可以通信的。上层动都不用动

我们再看左边 mac_C mac_R这个报头,交给路由器,路由器就把这个报头丢弃掉了,他的使命就完了,然后路由器会重新封装mac帧,用新的地址macR路由器 到mac_S.目标主机。

侧面也就回答了 IP 地址 和 mAC地址有什么区别呢?
IP地址,尤其是目的IP , 一般不会改变,协助我们进行路径选择。
mac地址,出局域网之后,源和目的都要被丢弃,让路由器重新封装。
则mac每经过一个设备,mac就都会变一下。


网络通信的基本脉络示意图

在这里插入图片描述

网络协议栈学的再多,我们要去伪存真,所以的数据最后都要经过物理上的这根网线传输。
那路由器是怎么知道数据包要去哪一个局域网呢?
实际上是和IP地址有关的。

总结

把数据包在不同层都会有不同的名字
一般在应用层把数据包叫做 请求与响应 但应用层谈的少。
传输层 叫做 数据段
网络层 叫做 数据报
链路层 报头+有效载荷 也就是数据包 也就是报文 叫做数据帧
在这里插入图片描述

再说一个,封装和解包 要明白的是不仅可以在双方主机贯穿整个协议栈封装解包,他也可以在路由器中进行局部解包和封装。

命令ifconfig

查网络接口eth0 和 本地环回

在这里插入图片描述
ip地址 是一个内网IP 先不管
在这里插入图片描述

每一个以点分割四个区域,每一个区别范围【0,255】每一个字段用8个bit表示就可以了
ip一共是4字节。
点分十进制的IP地址

ether 翻译 就是 以太
在这里插入图片描述

mac地址
都是十六进制数 ,冒号分割对应的就是一个字节,一共6个字节总共48位

网络编程套接字

在进行网络通信的时候,是不是我们的两台机器在进行通信呢?
在这里插入图片描述

1.网络协议中的下三层,主要解决的是,数据安全可靠的送到远端机器
2.用户使用应用层软件,完成数据发送和接受的。
先把这个软件启动起来也就是进程!
下三层通信只是手段,软件数据交互才是目的。

我们日常网络通信的本质:就是进程间通信!!

曾经学习过得进程间通信,需要让两个进程看到同一个份资源,今天这个资源就是网络

所以网络通信在应用层就叫做进程间通信

端口号

端口号可以用来标识应用层中,系统中唯一的进程
端口号无论对于客户的或者服务端,都能唯一的标识该主机上的一个网络应用层的进程。
在这里插入图片描述
进程可能有10个8个,但是网络协议栈在每个OS里只有一套,所以协议栈作为公共资源他要决定把数据转给哪一个进程。
所以需要有端口号能被应用层绑定,并且能被传输层识别,这样传输层就能把数据交给指定的一个进程了。

认识端口号

端口号是传输层协议的内容,但通常需要在应用层要用到的。
在这里插入图片描述
在这里插入图片描述
源IP 源端口 + 目的ip 目的端口 标识全网唯二的两个进程

这种基于IP+端口号的通信方式,我们把它叫做socket

socket 翻译为 插座 就好比客户端和服务端把插头插在插座上,就叫建立好链接了。

端口号 vs 进程pid

pid已经能够标识一台主机上进程的唯一性了,为什么还要搞一个端口号???
1.不是所有的进程都要网络通信,但是所有进程都要有pid (那我就用pid呢?)
2.系统和网络功能解耦,如果有天OS变了,那网络也得跟这边,牵一发而动全身。

进程要绑定端口号,请问传输层是怎么把报文转发给抖音服务器的?
你说的绑定究竟是什么意思?
在OS内部会在传输层中形成一张哈希表,每一个表中的元素都是一个task_struct* 进程PCB对应的指针
所谓的抖音服务器进程绑定端口号的本质,是拿着要绑定的端口号在哈希表作哈希运算,找到一个位置,如果已经被占用就不能绑定了,因为一个端口号只能被一个进程绑定,如果端口号当前没有被使用,所以把进程PCB地址放到哈希表中,哈希表不理解想象成指针数组就可以。
这里仅仅是示意,真实的表没这么粗糙。
在这里插入图片描述
但原理就是这样。

LINUX下一切皆文件
所以在整个网络中,在进程角度如何看待对应的网络呢?
我们实际上把网络也当成文件,所以怎么让进程读到这个数据呢?如果他在上层网络本身也是一个文件的形式的话,上层要读取数据的话,有文件就必须要有文件缓冲区,只需要把网络收到的有效载荷放到我这个进程所打开的网络文件缓冲区里,最后上层就跟读文件一样把数据读出来了,当然UDP有些差别,但是Tcp就是这样的。

绑定的过程就是把进程PCB和系统中的哈希表关联起来,最后收到报文,执行哈希算法找到进程就能交给进程数据。

我们的客户端,如何知道服务期的端口号是多少?
当然服务期也要知道客户端的端口号。
你有没有发现你所有的网络行为都是你在主动的。
你打开抖音,你玩天猫。
所以让服务期知道客服端的端口号是比较容易的。
但是客户端怎么知道服务期的端口号是多少?
一般服务器的端口号必须是众所周知的,精心设计,被客户端知晓的。
你安装的客户端都是人家开发的,能不知服务期端口号是多少?直接内置进去了

一个进程可以绑定多个端口号吗?
可以的
一个端口号可以被多个进程绑定吗?
不可以,从哈希表里都能看出来,一个进程如果被多个端口绑定了,经过对应的哈希找到的进程就不唯一了,从传输层就无法进行分用了,没法确定数据向上交付给哪一个进程了。

认识TCP协议
tcp叫做传输控制协议
在这里插入图片描述
侧重点放到面向连接,提供可靠性

tcp面向连接
tcp通信时,需要客户端向服务器发起连接的请求,连接建立成功才能正确发送数据。
就好像你打电话得先喂,保证信道畅通。
这也是保证可靠性的一种。

UDP叫做用户数据报协议

在这里插入图片描述
就像发邮件一样,用不着建立链接
从传输层从上往下发送给对端,对端收没收到我也不关心了。也就不可靠
为什么传输层要有两个特别极端的协议呢?
UDP不保证可靠性,那你用他干嘛,只有TCP完了呗。
TCP和UDP本身可靠不可靠是中性词,没有褒贬。

TCP保证可靠性是有带价的,你得重发,保证不乱序,所以TCP做了更多的工作,维护性更差。

UDP不维护原始报文,丢包跟我没关系,向下交付就完了,他就非常简单。

每一个协议在特定的场景中都有发挥的地方。

TCP在银行转账,手机支付宝

udp在直播,录播,信息派发。

TCP保证可靠传输,前提是他不是一个万能的协议,我没有网你也给我传不了,我能帮你处理网络连通的情况下出现的数据丢失问题,网都联不通就不要强调TCP可靠了。

目前知道TCP可靠,UDp不可靠完了。

网络字节序

在这里插入图片描述

网络中有大端机,也有小端机
你发1234,到对方就变成4321了
如果利用携带大小端字段来甄别,这个字段同样会被乱序

网络标准 规定 所有网络信息全部大端
你要是小端那就把报文从大端转小端
在这里插入图片描述
收发数据我不管你是大端还是小端,反正都是按内存从低到高发出。

口诀 大小端问题
低权值位 放在 低地址位 小端
小 小 小
反之 大端
当然大 大 大 也是小端

大部分的字段转换会由OS帮我们完成

但是有些字段需要我们自己转,
比如,源IP 目的IP和 源端口 目的端口
但不是自己写,系统提供了借口
在这里插入图片描述
host to net long

long or short 4字节 2字节的转化
对应IP和端口,后面绑定IP和端口号时就需要使用转换函数。

套接字编程的种类

  1. 域间套接字编程 ----- 同一个机器内通信
  2. 原始套接字编程----用于编写网络工具
  3. 网络套接字编程-----用户间的网络通信

开发者想把网络接口统一抽象化
也就是说域间套接字也同样使用这套接口
在这里插入图片描述
那怎么统一,函数接口参数的类型必须是统一的。
bind函数内部利用16位地址类型做判断,说明是域间还是网络套接字
在这里插入图片描述

bind参数中const struct sockaddr* address指向sockaddr_in就使用端口或IP下面的这些字段,如果指向un就用路径名这个字段
这就是典型的多态的特点。
struct sockaddr是基类,sockaddr_in,sockaddr_un都是子类
通过不同数据类型就能让我们访问不同的数据

未来网络通信,我们用填充属性结构体是struct sockaddr_in。
但提供的接口类型实际上是struct sockaddr,所以你需要把结构体struct sockaddr_in强转才能用接口。

为什么这么麻烦?
你直接把网络接口设置为void* 不就是通用指针接口吗?
我们把void指针解引用,再强转为short类型,16位地址类型不就提出来了。然后我在做判断不就更好吗?为什么要设计成这样的结构呢?
网络接口出来时C语言还没有void

现在有了你也改不了了,因为有使用这套接口的老代码。

未来创建套接字时,需要考虑大小端问题,设计通用接口问题,接口使用还要强转的问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词