【Linux网络编程】--Socket编程预备

一、理解源IP地址和目的IP地址

前面我们提到了IP地址其作用是:在网络中标识主机的唯一性

我们再来想想我们主机之间进行网络通信的原因是啥?

前面我们也提到了,是用户发出的指令、所以是用户之间需要进行通信,而我们主机之间的通信只是用户之间进行通信的手段,根本目的是:用户之间要通信。

而且我们的用户要通信,那么本质上不就是一个进程么,那么不就是两个进程之间的通信么?

不过这两个进程和我们前面学习管道的时候的进程间通信不太一样,这里的是不同主机之间的进程进行通信。

那么就有个疑问了?

我们的一台主机上通常是同时运行这非常多的应用程序的,那么我们的报文是如何精准的将其传输到对应的进程的呢?

所以源IP地址和目的IP地址只是标识在网络通信中标识主机唯一性的。

我们还需要标识符来标识用户层中,进程的唯一性的。

二、认识端口号

上面我们提到了,主机之间通信只是用户之间需要通信的手段,用户之间的通信才是目的。

然后我们的一个主机中的进程是非常多的,那么我们需要将其管理起来,所以先描述后组织,我们又引入一个概念,端口号(port)

端口号是传输层协议的内容。

是用来标识一个进程,告诉操作系统,当前这个数据要交给那个进程进程处理。

所以整个通信=IP地址+端口号

一个端口号对应一个进程,对于一些不需要进行通信的进程,我们不用考虑给其分配端口号。

对于端口号的管理,其是使用的一个哈希表的数据结构进行管理的,这是因为对于端口号,我们做的最多的操作就是查找端口号对应的进程。

端口号是一个2字节的16位的整数,其划分范围如下:

0-1023:知名端口号、HTTP,FTP,SSH等这些广为使用的应用层协议,他们的端口号都是固定的。

1024-65535:操作系统动态分配的端口号,客户端程序的端口号,就是给操作系统这个范围进行分配的。

三、端口号和pid

前面我们学习操作系统部分,对于进程,其也有标识其唯一性的标识符:pid,那么我们为啥不直接使用呢?

pid是操作系统上的概念,而端口号是网络层面上的概念,这也是将我们的网络通信和操作系统部分进行解耦,降低耦合度。

然后还有一个问题就是。并不是所有的进程都需要进行通信,所以在网络层面上,也不需要将所有的pid都使用到,我们只需要将会进行通信的进程组织起来即可。

所以综上所述:

IP地址是用来标识互联网中唯一的一台主机、port是用来标识主机上唯一的一个进程。

IP+prot就可以标识互联网中的唯一一个进程

所以进程通信的时候实质上是两个互联网进程代表人来进行通信。

{srclp,srcport,dstip,dstport}的四元组就可以标注互联网中的通信。

互联网中的通信本质:也是两个进程间进行通信

我们将ip+port叫做套接字:socket。

四、传输层中的典型代表

我们已经知道的是传输层其实是在我们的操作系统内核的,所以我们需要通过网络协议进行通信的话,那么就需要通过调用传输层提供的系统调用来实现网络通信。

下面我们先来认识在传输层中,常见的两个协议:

TCP协议:(传输控制协议)

我们此处就只是对其有一个简单认识即可,后续我们会对其进行详细讲解的。

其有如下特点:

是传输层的一个协议,需要先进行连接,其是一个可靠传输,对于数据的丢包等都有处理,其是面向字节流的。

UDP协议:(用户数据报协议)

是在传输层的一个协议,不需要先进行连接,然后其是不可靠传输,是面向数据报的。

五、网络字节序

首先我们知道,在计算机的存储中,我们是分为大小端模式的,磁盘文件系统中对多字节数据相对文件中的地址也是有大小端之分的。

我们的网络通信的手段是两个主机之间通信,那么有个问题:

如果发送方和接收方机器对于数据的存储的方式不一样,就比如现在A主机是小端机器,B主机是大端机器,那么就会导致到用户层上的数据会有出入。

那么这个如何解决呢?

首先,我们知道的是,计算机的出现要比网络要早,所以大小端机器的不同,这个是客观存在了的,如果说去要求计算机的硬件上,统一标准,那么以前的那些机器不就不能进行网络通信了嘛。

那么有一个办法:

就是让我们的报文中,携带我们机器的大小端存储方式,然后接收方根据这个来决定是否需要对这个数据进行大小端的处理,但是这个也会有个缺点,就是很浪费网络资源,就比如我要给主机B发送个你好,然后我还要携带一个大小端的信息,那么网络资源的利用率就特别低了。

所以上面的方法可行,但是不是最优解。

在TCP\IP协议中,其规定,所有进入网络的数据,都是大端的。

所以小端存储的机器,在进入网络前,要先将其存储的数据转为大端。

然后接收方,根据自己的大小端方式来处理。

我们可以调用下面的库函数来做网络字节序和主机字节序的转换

这些函数名很好记, h 表⽰ host , n 表⽰ network , l 表⽰ 32 位⻓整数, s 表⽰ 16 位短整 数。

例如 htonl 表⽰将 32 位的⻓整数从主机字节序转换为⽹络字节序,例如将IP地址转换后准备发送。

如果主机是⼩端字节序,这些函数将参数做相应的⼤⼩端转换然后返回;

如果主机是⼤端字节序,这些函数不做转换,将参数原封不动地返回。

总结:

所有发送到网络上的数据都必须是大端排序的。

六、socket编程接口

socket常见的接口:

可以看到这几个接口都有一个struct sockaddr类型的结构体指针参数。

那么其实际上是啥呢?

首先sockaddr网络通信的设计者:其也是可以进行本地通信的。

所以总的来说我们的通信主要分为下面三种:

INET socket网络通信

unix 域间通信 socket 本地通信

raw socket 原始套接字

然后我们来看struct sockaddr的结构,可以看到其都有一个16位的地址类型,然后会根据传入的地址类型进行判断,其是要实现网络通信还是本地通信,所以这不就是我们的多态嘛。

相关推荐
笨蛋不要掉眼泪1 小时前
Java并发编程 :深入剖析LinkedBlockingQueue
java·开发语言·网络·并发
杨浦老苏1 小时前
网络连接实时可视化利器TapMap
网络·docker·可视化·监控·群晖
皮卡狮1 小时前
环境变量详解
linux
致Great2 小时前
Claude Code 上线 Dynamic Workflows:一句话调度 1000 个子智能体并行干活
java·linux·服务器
m0_738120722 小时前
渗透测试基础——黑盒测试下的Web漏洞挖掘与利用解析(一)
服务器·前端·网络·安全·php
网络与设备以及操作系统学习使用者2 小时前
零信任架构落地实践详解
运维·网络·学习·架构
满天星83035772 小时前
【Git】原理及使用(三)(分支管理)
linux·git
weixin_468466853 小时前
Prometheus监控服务部署与实战指南
服务器·后端·python·docker·自动化·prometheus
载数而行5203 小时前
Linux 2 基本实操(远程操控,远程传输,vi/vim编辑器,关机重启,xshell的用户登录注销)
linux