# issue 6 网络编程基础

一、网络的物理结构和光纤千兆网络

        首先,我们需要知道网络的物理结构——数据是如何从一台机器传输到另外一台机器的

        这个过程是非常重要的。现在很多人做软件开发,只会软件角度,这导致讲软件原理头头是道,但是连数据线都不会接,公司让组一个网络产品,网络设备要怎么买,买哪些东西,怎么组合成网络也不清楚,这严重影响软件的表现。

二、网络中的地址(IP)

并不是所有的地址都是可以用的

以0开头的地址都是不可用的

以0结尾的地址表示网段而不是具体的地址(可用但是不可访问)

224开头到239开头的地址,是组播地址,不可用于点对点的传输(组播可以理解为tcp/udp上面的广播)(组播可以极大的节约带宽,但是组播有个问题:容易形成网络风暴)

240开头到255开头的地址,是实验用的,保留,一般不做服务器地址

127.0.0.1保留的,回环网络的地址

0.0.0.0保留的,一般用于服务器监听的,表示全网段监听  

32位网络地址由4个字节构成       可以表示255*255*255*255个网络地址

Network:网络地址

Host:主机地址 

所以A类的网络地址(大型网络)只有7bit,所以网络内部最多容纳2^7个机器

B类地址(中型网络)只有14bit,所以最多65536个机器,然后每个最多65536个终端

C类地址(小型网络)

三、网络中的端口

公认端口(Well Known Ports):这类端口也常称之为"常用端口"。
        

        这类端口的端口号从0 到1024,它们紧密绑定于一些特定的服务。通常这些端口的通
信明确表明了某种服务的协议,这种端口是不可再重新定义它的作用对象。
        例如:80 端口实际上总是HTTP 通信所使用的,而23 号端口则是Telnet 服务专用的。443端口一般用于https服务(加密传输协议)
        这些端口通常不会像木马这样的黑客程序利用。

注册端口(Registered Ports):端口号从1025 到49151。


        它们松散地绑定于一些服务。也是说有许多服务绑定于这些端口,这些端口同样用于许
多其他目的。这些端口多数没有明确的定义服务对象,不同程序可根据实际需要自己定义,
如后面要介绍的远程控制软件和木马程序中都会有这些端口的定义的。
        记住这些常见的程序端口在木马程序的防护和查杀上是非常有必要的。常见木马所使用
的端口在后面将有详细的列表。

动态和/或私有端口(Dynamic and/or Private Ports):端口号从49152 到65535。


        理论上,不应把常用服务分配在这些端口上。实际上,有些较为特殊的程序,特别是一些木马程序就非常喜欢用这些端口,因为这些端口常常不被引起注意,容易隐蔽。

        端口并非服务器才会使用,客户端也一样会使用端口

四、什么是协议

TCP 协议包头说明

SSH 数据包头结构

        协议就是一种网络交互中数据格式交互流程的约定 

        通过协议,我们可以与远程的设备进行数据交互
        请求或者完成对方的服务

        协议就是计算机中的语言(语言就需要遵循一些规定,这些规定就是协议)

五、TCP协议的基础

        传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流传输层通信协议

注意:TCP是可靠的协议(你发送了数据则一定服务器端收到了),区别于UDP协议,UDP协议是不可靠的。(可靠的代价就是牺牲了性能)

        基于字节流:可以发送1个字节,或者上w个字节,数据是字节流,这个是纯字节流,没有回车什么的
交互流程:

        当物理连接中断过后,只有超时才能解决。默认的超时可能长达两个小时。

        如何弥补呢?心跳包的机制 (除了正常的发送TCP数据之外,我们还会发送心跳包数据,每个心跳包服务器都要给予应答,这个收发的过程就表现了物理的连接,当三次没有收到应答,就表明物理连接断开了)(说人话就是:强制询问双方是否在线,如果种植,或者异常连续超过若干次(一般为三次)那么物理连接就断开了)

六、什么是套接字

        网络编程就是编写程序使两台连网的计算机相互交换数据。两台计算机之间用什么传
输数据呢?首先需要物理连接。在此基础上,只需考虑如何编写数据传输软件。但实际上这
也不用愁,因为操作系统会提供名为"套接字"(socket)的部件。套接字是网络数据传输用
软件设备(软件模块)
。即使对网络数据传输原理不太熟悉,我们也能通过套接字完成数据传输。因此,
网络编程又称为套接字编程。

应用层: 就是程序,程序就是在应用层

网络层:解析IP(通过协议解析)

用户直接用IP协议就是原始的套接字,原始套接字在逆向和安全中可以用来伪装包头

七、套接字的创建

        套接字有很多种,其中用的最多的是TCP和UDP

       我们先讨论TCP 套接字。TCP套接字可以比喻成电话机。实际上,电话机也是通过固定电话网(telephone network)完成语音数据交换的。就如同于:创建一个套接字就相当于是安装了一部电话机。

#include<sys/socket.h>
int socket(int domain,int type,int protocol);

成功时返回文件描述符,失败时返回-1。
domain 域,(包括地址协议族和协议协议族)套接字中使用的协议族(Protocol Family)信息。                                                         (两孔或者三孔插座)
type 套接字数据传输类型信息。            (圆孔或者方孔)
protocol 计算机间通信中使用的协议信息(运输层和网络层的协议,不是应用层的协议(例如http、ssh))。(很复杂,由前面两个确定)          (220v或者110v)

八、socket函数

参数一:domain (Protocol Family)(域)
                                        

                                                头文件sys/socket.h 中声明的协议族

        在一般的网络编程程序里面,PF_INET 对应的IPV4 互联网协议是最常用的,我们目前只需要掌握这类协议族。 

参数二:套接字类型:type


        套接字类型指的是套接字的数据传输方式,通过socket 函数的第二个参数传递,只有这样才能决定创建的套接字的数据传输方式。(告诉系统怎么传输这个数据)
        那为什么已通过第一个参数传递了协议族信息,还要决定数据传输方式?问题就在于,决定了协议族并不能同时决定数据传输方式,换言之,socket 函数第一个参数PF_INET 协议族中也存在多种数据传输方式。
        套接字类型1∶面向连接的套接字(SOCK_STREAM)---TCP
        如果向socket 函数的第二个参数传递SOCK_STREAM,将创建面向连接的套接字。
        什么是面向连接呢?


就如同上图一样: 数据(糖果)的传输方式有三个特点:
        A 传输的过程数据不会丢失(收没收到数据是知道的)
        B 按顺序传输
        C 传输的过程中不存在数据边界

数据边界是啥?
        举个例子:"100 个糖果是分批传递的,但接收者凑齐100 个后才装袋。再比如:传输数据的计算机通过3 次调用write 函数传递了100 字节的数据,但接收数据的计算机仅通过1 次read 函数调用就接收了全部100 个字节。" 收发数据的套接字内部有缓冲(buffer),简言之就是字节数组。通过套接字传输的数据将保存到该数组。因此,收到数据并不意味着马上调用read 函数。只要不超过数组容量,则有可能在数据填充满缓冲后通过1 次read 函数调用读取全部,也有可能分成多次read 函数调用进行读取。也就是说,在面向连接的套接字中,read 函数和writ 函数的调用次数并无太大意义。所以说面向连接的套接字不存在数据边界。
面向连接的套接字:
        "可靠的、按序传递的、基于字节的面向连接的数据传输方式的套接字"

        套接字类型2∶面向消息的套接字(SOCK DGRAM)---UDP
        如果向socket 函数的第二个参数传递SOCK DGRAM,则将创建面向消息的套接字。面
向消息的套接字可以比喻成高速移动的摩托车快递。

        数据(包裹)的传输方式有四个特点:
        A 强调快速传输而非传输顺序
        B 传输的数据可能丢失也可能损毁
        C 传输的过程中不存在数据边界
        D 限制每次传输的数据大小。(不能超过UDP单个包的大小,如果超过了就需要拆包)
面向消息的套接字:
        "不可靠的、不按序传递的、以数据的高速传输为目的的套接字"

参数三:protocol 计算机间通信中使用的协议信息
        

        大部分情况下可以向第三个参数传递0,
        除非遇到以下这种情况∶
        "同一协议族中存在多个数据传输方式相同的协议"
        数据传输方式相同,但协议不同。此时需要通过第三个参数具体指定协议信息。

九、bind函数(将套接字和对应的地址端口关联)

#include<sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);

成功时返回0,失败时返回-1。
        调用bind 函数给套接字分配地址后,就基本完成了接电话的所有准备工作。
        如果把套接字比喻为电话,那么目前只安装了电话机。
        接着就要给电话机分配号码的方法,即给套接字分配IP 地址和端口号。就是用的bind 函数。

struct sockaddr *myaddr:对于这个结构体指针,实际中,我们并不会填这个指针,而是填一系列结构体的地址,因为这个地址并不是一个结构体可以说清楚点

socklen_t addrlen:这个填写上面那个参数的实际长度,用于解析第二个参数。

参数一:套接字描述符sockfd
        要分配地址信息(IP 地址和端口号)的套接字文件描述符。
参数二:存有地址信息的结构体变量地址值myaddr
        网络地址
                4 字节地址族
                IPv4(Internet Protocol version 4)
                16 字节地址族
                IPv6(Internet Protocol version 6)

        只需通过IP 地址的第一个字节即可判断网络地址占用的字节数,因为我们根据IP 地址的边界区分网络地址:
        A 类地址的首字节范围∶0~127
        B 类地址的首字节范围∶128~191
        C 类地址的首字节范围∶192~223

        A 类地址的首位以0 开始
        B 类地址的前2 位以10 开始
        C 类地址的前3 位以110 开始
端口
        IP 用于区分计算机,端口用于在同一操作系统内为区分不同套接字而设置的,因此无法将1 个端口号分配给不同套接字。另外,端口号由16 位构成,可分配的端口号范围是0-65535。但0-1023 是知名端口,一般分配给特定应用程序。另外,虽然端口号不能重复,但TCP 套接字和UDP 套接字不会共用端口号,所以允许重复。例如∶如果某TCP 套接字使用9190号端口,则其他TCP 套接字就无法使用该端口号,但UDP 套接字可以使用。
        总之,数据传输目标地址同时包含IP 地址和端口号,只有这样,数据才会被传输到最
终的目的应用程序(应用程序套接字)

地址信息的表示

struct sockaddr_in
{
sa_family//地址族(Address Family)
sa_family_t sin_family;// //地址族(Address Family)
uint16_t sin_port; // 16 位TCP/UDP 端口号
struct in_addr sin_addr; //32 位IP 地址
char sin_zero[8]; //不使用    用于对齐
}  


该结构体中提到的另一个结构体in_addr 定义如下,它用来存放32 位IP 地址。
 

struct in_addr
{
In_addr_t s_addr; //32 位IPv4 地址
};

成员sin_family --- 地址族(Address Family)


成员sin_port
        该成员保存16 位端口号   0-65535,一般而言0-1024不要用,这一般留给系统用的
成员sin_addr

        该成员保存32 位IP 地址信息,且也以网络字节序保存。为理解好该成员,应同时观察结构体in addr。但结构体in addr 声明为uint32t,因此只需当作32 位整数型即可。

成员sin_zero
        无特殊含义。只是为使结构体sockaddr in 的大小与sockaddr 结构体保持一致而插入的成员。必需填充为0,否则无法得到想要的结果。

网络字节序(一般先传输低位)与地址变换
大端序(Big Endian)∶高位字节存放到低位地址。
小端序(Little Endian)∶高位字节存放到高位地址。
字节序转换:
. unsigned short htons(unsigned short);
. unsigned short ntohs(unsigned short);
. unsigned long htonl(unsigned long);
. unsined long ntohl(unsigned long);

通过函数名应该能掌握其功能,只需了解以下细节。
. htons 中的h 代表主机(host)字节序。
.htons 中的n 代表网络(network)字节序。
ntohs 可以解释为"把short 型数据从网络字节序转化为主机字节序"

参数三:第二个结构体变量的长度
一般直接用sizeof 第二个参数就行

测试代码:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
void lession57() 
{int sock=socket(PF_INET, SOCK_STREAM, 0);//创建一个套接字if (sock != -1) {struct sockaddr_in addr; addr.sin_family = AF_INET;//地址协议族 addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //设置ip地址addr.sin_port = htons(9527);//设置端口      主机字节序转换为网络字节序int ret=bind(sock, (struct sockaddr*)&addr, sizeof(addr));if (ret != 0) {//TODO  报错}}
}

十、listen和accept

listen 函数

#include <sys/socket.h>
int listen(int sock,int backlog);

→成功时返回0,失败时返回-1。
sock希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端
套接字(监听套接字)。
backlog 连接请求等待队列(Queue)的长度,若为5,则队列长度为5,表示最多使5 个连
接请求进入队列。

        由上图可知作为listen 函数的第一个参数传递的文件描述符套接字的用途

        客户端连接请求本身也是从网络中接收到的一种数据,而要想接收就需要套接字。此任务就由服务器端套接字完成。服务器端套接字是接收连接请求的一名门卫或一扇门。
        客户端如果向服务器端询问∶"请问我是否可以发起连接?"
        服务器端套接字就会亲切应答∶"您好!当然可以,但系统正忙,请到等候室排号等待,准备好后会立即受理您的连接。"
        调用listen 函数即可生成这种门卫(服务器端套接字)
        listen函数的第二个参数决定了等候室的大小。等候室称为连接请求等待队列,准备好服务器端套接字和连接请求等待队列后,这种可接收连接请求的状态称为等待连接请求状态。
        listen 函数的第二个参数值与服务器端的特性有关,像频繁接收请求的Web 服务器端至
少应为15。另外,连接请求队列的大小始终根据实验结果而定。

accept 函数

#include<sys/socket.h>
int accept(i
nt sock,struct sockaddr * addr, socklen_t*addrlen);
accept默认是阻塞的,直到有连接进来才会返回

→成功时返回创建的套接字文件描述符,失败时返回-1。
参数sock:服务器套接字的文件描述符。
参数addr:保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址
变量参数填充客户端地址信息。(只能作为参考,因为可能通过伪装包头进行错误的信息,但正常情况下是没问题的)
参数addrlen:第二个参数结构体的长度,但是存有长度的变量地址。函数调用完成后,该
变量即被填客户端地址长度。

        调用listen 函数后,若有新的连接请求,则应按序受理。如果在与客户端的数据交换中使用门卫,那谁来守门呢?因此需要另外一个套接字,但没必要亲自创建。此时accept 应运而生。
        accept 函数受理连接请求等待队列中待处理的客户端连接请求。函数调用成功时,accept
函数内部将产生用于数据I/O 的套接字,并返回其文件描述符。套接字是自动创建的,并自动与发起连接请求的客户端建立连接。上图展示了accept 函数调用过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

彻底理解quadtree四叉树、Octree八叉树 —— 点云的空间划分的标准做法

1.参考文章&#xff1a; &#xff08;1&#xff09;https://www.zhihu.com/question/25111128 这里面的第一个回答&#xff0c;有一幅图&#xff1a; 只要理解的四叉树的构建&#xff0c;对于八叉树的构建原理类比方法完全一样&#xff1a;对于二维平面内的随机分布的这些点&…

飞塔防火墙只允许国内IP访问

飞塔防火墙只允许国内IP访问 方法1 新增地址对象&#xff0c;注意里面已经细分为中国内地、中国香港、中国澳门和中国台湾 方法2 手动新增国内IP的对象组&#xff0c;目前好像一共有8632个&#xff0c;每个对象最多支持600个IP段

超详细ensp配置VRRP和MSTP协议

一、简介 1、什么是VRRP&#xff1a; &#xff08;1&#xff09;VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;的概念&#xff1a; VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;指的是一种实现路由器冗余备份的协议&#xff0c;常用于…

东风破捉妖师横空出世

一.异动拉升实时监测 东风破就像是一个大盘监测平台&#xff0c;是现实版的捉妖师&#xff0c;一旦妖股横空出世&#xff0c;就会在东风破面前原形毕露。东风破AI算法逻辑是监测存在异动拉升的股票&#xff0c;实时分析上证&#xff0c;深证&#xff0c;创业和科创板的股票数据…

Scala—数组(不可变数组Array、可变数组ArrayBuffer)用法详解

Scala集合概述-链接 大家可以点击上方链接&#xff0c;先对Scala的集合有一个整体的概念&#x1f923;&#x1f923;&#x1f923; 在 Scala 中&#xff0c;数组是一种特殊的集合类型&#xff0c;可以是可变的也可以是不可变的。 1. 不可变数组 在 Scala 中&#xff0c;不可变…

数据库期末复习题库

1. Mysql日志功能有哪些? 记录日常操作和错误信息&#xff0c;以便了解Mysql数据库的运行情况&#xff0c;日常操作&#xff0c;错误信息和进行相关的优化。 2. 数据库有哪些备份方法 完全备份&#xff1a;全部都备份一遍表备份&#xff1a;只提取数据库中的数据&#xff0…

TsingtaoAI具身智能高校实训方案通过华为昇腾技术认证

日前&#xff0c;TsingtaoAI推出的“具身智能高校实训解决方案-从AI大模型机器人到通用具身智能”基于华为技术有限公司AI框架昇思MindSpore&#xff0c;完成并通过昇腾相互兼容性技术认证。 TsingtaoAI&华为昇腾联合解决方案 本项目“具身智能高校实训解决方案”以实现高…

如何使用 Chrome 无痕浏览模式访问网站?

无痕浏览&#xff08;Incognito Mode&#xff09;是 Google Chrome 浏览器提供的一种隐私保护功能&#xff0c;它允许用户在一个独立的会话中浏览网页&#xff0c;而不会记录用户的浏览历史、下载历史、表单数据等。这对于希望保护个人隐私或进行临时性匿名浏览的用户来说非常有…

如何从 Hugging Face 数据集中随机采样数据并保存为新的 Arrow 文件

如何从 Hugging Face 数据集中随机采样数据并保存为新的 Arrow 文件 在使用 Hugging Face 的数据集进行模型训练时&#xff0c;有时我们并不需要整个数据集&#xff0c;尤其是当数据集非常大时。为了节省存储空间和提高训练效率&#xff0c;我们可以从数据集中随机采样一部分数…

彻底理解如何保证ElasticSearch和数据库数据一致性问题

一.业务场景举例 需求&#xff1a; 一个卖房业务&#xff0c;双十一前一天&#xff0c;维护楼盘的运营人员突然接到合作开发商的通知&#xff0c;需要上线一批热门的楼盘列表&#xff0c;上传完成后&#xff0c;C端小程序支持按楼盘的名称、户型、面积等产品属性全模糊搜索热门…

微信小程序下拉刷新与上拉触底的全面教程

微信小程序下拉刷新与上拉触底的全面教程 引言 在微信小程序的开发中,用户体验至关重要。下拉刷新和上拉触底是提高用户交互体验的重要功能,能够让用户轻松获取最新数据和内容。本文将详细介绍这两个功能的实现方式,结合实际案例、代码示例和图片展示,帮助开发者轻松掌握…

vue3项目搭建-6-axios 基础配置

axios 基础配置 安装 axios npm install axios 创建 axios 实例&#xff0c;配置基地址&#xff0c;配置拦截器,目录&#xff1a;utils/http.js 基地址&#xff1a;在每次访问时&#xff0c;自动作为相对路径的根 // axios 基础封装 import axios from "axios";…

23种设计模式-抽象工厂(Abstract Factory)设计模式

文章目录 一.什么是抽象工厂设计模式&#xff1f;二.抽象工厂模式的特点三.抽象工厂模式的结构四.抽象工厂模式的优缺点五.抽象工厂模式的 C 实现六.抽象工厂模式的 Java 实现七.代码解析八.总结 类图&#xff1a; 抽象工厂设计模式类图 一.什么是抽象工厂设计模式&#xff1f…

【Linux探索学习】第十七弹——进程终止:深入解析操作系统中的进程终止机制

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在操作系统中&#xff0c;进程终止是一个至关重要的阶段&#xff0c;它标志着进程的生命周期结束。进程终止可能是因为任务完成&#xff0…

介绍一下strupr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strupr(arr)&#xff1b;函数是把arr数组变为大写字母 格式 #include<string.h> strupr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…

【VRChat 全身动捕】VIVE 手柄改 tracker 定位器教程,低成本光学动捕解决方案(持续更新中2024.11.26)

更新 0.0.1&#xff08;2024/11/26&#xff09;&#xff1a; 1.解决了内建蓝牙无法识别、“steamVR 蓝牙不可用” 的解决方案 2.解决了 tracker 虽然建立了连接但是在 steamVR 界面上看不到的问题 3.解决了 VIVE 基站1.0 无法被蓝牙识别 && 无法被 steamVR 搜索到 &…

Web 端语音对话 AI 示例:使用 Whisper 和 llama.cpp 构建语音聊天机器人

大语言模型&#xff08;LLM&#xff09;为基于文本的对话提供了强大的能力。那么&#xff0c;能否进一步扩展&#xff0c;将其转化为语音对话的形式呢&#xff1f;本文将展示如何使用 Whisper 语音识别和 llama.cpp 构建一个 Web 端语音聊天机器人。 系统概览 如上图所示&…

网络地址转换

NAT概述 解决公有地址不足&#xff0c;并且分配不均匀的问题 公有地址&#xff1a;由专门的机构管理、分配&#xff0c;可以在因特网上直接通信 私有地址&#xff1a;组织和个人可以任意使用&#xff0c;只能在内网使用的IP地址 A、B、C类地址中各预留了一些私有IP地址 A&…

电脑无互联网连接怎么解决?分享5种解决方案

无互联网连接是指设备无法与互联网进行通信或连接失败。这可能会导致我们无法正常上网&#xff0c;给我们的日常生活和工作带来很大的不便。但请不要担心&#xff0c;下面将为您介绍一些解决无互联网连接问题的方法。 一、检查网络是否正常连接 首先&#xff0c;确保您的路由器…

使用 F5 TTS 文字转音频

F5 TTS 支持 ZeroShot 音频克隆&#xff0c;只有将需要音频传给模型&#xff0c;模型既可以生成以对应声音生成的音频&#xff0c;F5 最强大的地方就是可以使用定制的人声。F5 使用了 DIT 架构进行训练&#xff0c;结构如下&#xff1a; 本地使用 F5 TTS F5 使用很简单&#x…