C++网络编程基础

协议

在这里插入图片描述
协议:收到数据后,多出来的那一部分,也叫一种 “约定”,一整套的自硬件到软件,都有协议,需要有人定制,也需要有人实现

当通信距离边长后,如何保证将数据交给下一跳主机,如何定位目标主机,如何处理报文出错,如何使用送达的数据等问题,都需要对应的协议

网络的层协议:和软件的层状结构一样,实现了各个部分代码的解耦,更容易维护,只需要考虑各个子问题即可。

![[Pasted image 20240603094511.png]]

网络协议一般叫:TCP/IP 协议,是在内核中实现的
网络编程:用户在操作系统的用户层使用系统调用,来实现网络层的功能
网络库:对网络层的系统调用进行封装,简化开发流程

任何操作系统都必须基于 OSI 标准实现网络协议栈,所以在不同的系统中,网络调用接口大同小异

报头使用C语言描述的结构体,client 和 server 之间是,都是可以识别这个报头的,因为client 和 server 描述报头的源代码都是一样的。

局域网通信

局域网通信:在同一个局域网中,两台主机是可以直接通信的,(局域网中建房间,玩游戏)
原理:两台主机在局域网中通信,局域网中所有主机都能收到消息,只不过通过 Mac 地址(网卡地址)来区分谁接受,其他不接收的主机会选择将消息直接丢弃掉
但有可能同一时刻,局域网中由多台主机在同时发消息,就可能会形成数据碰撞(丢包),那么发送方主机就会执行碰撞避免算法(休息一会再重发)

ifconfig:可查 Linux 主机的 Mac 地址(Mac只在局域网内部有效)

要正确的发送消息,再同一时刻,只允许一台主机在局域网中发消息,因此,局域网中的设备少,越安全,局域网中消息是否能发送成功是基于概率的,因此也叫 以太网(例如运动会操场上,消息发不出去一直丢包,就是因为几千人都访问的是附近同一个基站,而当操场上只有几个人的时候,消息特别流畅)

用系统的观点:局域网就是一个临界资源,主机在局域网出往另一台主机发送消息就是访问临界区代码,碰撞检测和碰撞避免、重发就是完成互斥访问,维护临界资源,单独发送,就是独占网络资源

用户之间通信时,消息在双方两台主机上,都要贯穿协议栈(软件->硬件 ——> 硬件->软件)

在这里插入图片描述

封装报头:在自己拿到的报文的基础上,添加同层协议的报头
每层协议都会封装自己对应的报头,也要考虑如何将收到的报文中,报头和有效载荷进行分离,如何将自己的有效载荷,交给上层的协议。

IP 地址

Linux 查看 ip 地址:ifconfig

在这里插入图片描述

windows 查看 ip 地址:ipconfig

在这里插入图片描述

整个ip 地址的范围:[0,255].[0,255].[0,255].[0,255] ,也叫点分十进制

在语言视角,这种点分十进制的 ip 地址,C++种可以使用字符串来表示

IP 地址分为公网ip内网ip,两个 ip 地址加起来,才是所有的 ip 地址,一般在 Linux 或 windows 上直接见到或查到的 ip 地址,都是内网ip,但如果要使自己的服务被别人看到,就要使这个服务或对用的服务器具备公网ip

一般来说,ip地址表示公网 ip,用来表示互联网种唯一的一台主机,也可以表示局域网种唯一的一台主机
实际网络通信时只需要4个字节即可表示一个网络 ip,8* 4 = 32,32个比特位就能表示任意一个网络 ip,占用的字节数较少

那么如何将整形存储的ip地址转化为便以阅读的点分十进制这种字符串风格的ip地址呢?
在这里插入图片描述

ip地址Mac地址 的区别:

ip 地址是永远不变的,在互联网中唯一,而 Mac地址是在局域网中不变的,但出了局域网后会变

Mac 地址意义:标识主机唯一性,用于局域网通信
IP 地址意义:帮助用于路径选择,目标ip

![[Pasted image 20240603163120.png]]

同层协议要发的,就是同层协议要收的!!

在 ip 层往下,报头在变,而ip层往上是一样的,因此也叫网咯ip地址
相当于在全球所有主机层面上,搭建了一层软件层,通过ip地址,就可以屏蔽底层所有局域网通信的网络差异了

网络通信的示意图:

在这里插入图片描述

网络通信的本质

网络之间的通信,本质上就是进程间通信

对双方主机的两个进程而言,需要先将数据发送到对方的主机(ip地址),再找到指定的进程(port:端口号),就能实现通信

ip地址用来标识互联网中唯一的一台主机;port端口号用来标识该指定机器中进程的唯一性

那么(ip, port) 则可以用来表示互联网中唯一一个进程,ip + port 也叫网络套接字 socket

如何理解port:
一个端口号和一个进程相绑定,一个进程可以绑定多个端口号,反之则不可以。
那么为什么不用进程pid来表示网络中进程的唯一性呢?
为了其他的进程模块和网络进行解耦(万一pid的规则变化,网络部分也不受影响),port是专门用于网络通信的

tcp 和 udp 协议

tcp 协议常用于可靠通信,适用于对数据要求比较高的场景(如游戏,传输重要文件等),复杂
udp 协议用于不可靠通信,适用于允许数据偶尔出现差错的场景(如体育赛事直播等),简单,快

这两个协议没有好坏之分,只是应用场景不同,如果不确定使用哪个的时候,就要 tcp,毕竟复杂一点比丢包好

网络字节序

机器有大小端之分,大小端机器存储数据方式不同。大端是“正着存储”的,可读性较好,因此在网络传输时规定,所以到达网络的数据,必须时大端存储的,因此,如果是小端机,收发数据到网络时需要先转化为大端

网络主机数据转化接口

ip 地址为4个字节,使用 uint32_t,port 为2个字节,使用 uint_16

htonl、htons 是转网络,ntohl、ntohs 是转主机数据,使用这些接口可以自动识别机器的大小端,并将数据转化为需要的大小端数据。

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uintl6_t ntohs(uint16_t netshort);
  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值