【Linux】网络编程1

1.概念

局域网和广域网

局域网:局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。

广域网:又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。 IP(Internet Protocol):本质是一个整形数,用于表示计算机在网络中的地址。IP协议版本有两个:IPv4和IPv6。

IPv4(Internet Protocol version4):

使用一个32位的整形数描述一个IP地址,4个字节,int型

也可以使用一个点分十进制字符串描述这个IP地址: 192.168.247.135

分成了4份,每份1字节,8bit(char),最大值为 255

0.0.0.0 是最小的IP地址

255.255.255.255是最大的IP地址

按照IPv4协议计算,可以使用的IP地址共有 2^32 个。

IPv6(Internet Protocol version6):

使用一个128位的整形数描述一个IP地址,16个字节 也可以使用一个字符串描述这个IP地址:2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b 分成了8份,每份2字节,每一部分以16进制的方式表示 按照IPv6协议计算,可以使用的IP地址共有 2^128 个。

查看IP地址的方法:

cpp 复制代码
Linux:ifconfig

windows:ipconfig

端口

通俗的来讲,我要把一个快递送出去,我知道了这个人住在哪,但是这间房子住了很多户人家,我要把快递给那个人,我就要直到它的门牌号或者名字,所以,这个房子的地方就是IP地址,门牌号就是端口号。

端口的作用是定位到主机上的某一个进程,通过这个端口进程就可以接受到对应的网络数据了。

比如: 在电脑上运行了微信和QQ, 小明通过客户端给我的的微信发消息, 电脑上的微信就收到了消息, 为什么?

  • 运行在电脑上的微信和QQ都绑定了不同的端口
  • 通过IP地址可以定位到某一台主机,通过端口就可以定位到主机上的某一个进程
  • 通过指定的IP和端口,发送数据的时候对端就能接受到数据了

端口也是一个整形数 unsigned short ,一个16位整形数,有效端口的取值范围是:0 ~ 65535(0 ~ 216-1)。

计算机中所有的进程都需要关联一个端口吗,一个端口可以被重复使用吗?

不需要,如果这个进程不需要网络通信,那么这个进程就不需要绑定端口的

一个端口只能给某一个进程使用,多个进程不能同时使用同一个端口

1~1023 系统保留,由root用户使用
1024~4999 由客户端系统分配
5000~65535 由服务器端程序分配

网络模型

OSI七层网络模型

七层模型,又称OSI参考模型,即开放式系统互联,参考模型是国际标准化组织(ISO)指定的一个用于计算机或者通信系统间互联的标准体系,一般称为OSI参考模型或者七层模型。

TCP/IP四层协议

物理层:负责最后将信息编码成电流脉冲或其它信号用于网上传输

数据链路层:

数据链路层通过物理网络链路供数据传输。

规定了0和1的分包形式,

确定了网络数据包的形式;

网络层

网络层负责在源和终点之间建立连接;

此处需要确定计算机的位置,通过IPv4,IPv6格式的IP地址来找到对应的主机

传输层

传输层向高层提供可靠的端到端的网络数据流服务。

每一个应用程序都会在网卡注册一个端口号,该层就是端口与端口的通信

会话层

会话层建立、管理和终止表示层与实体之间的通信会话;

建立一个连接(自动的手机信息、自动的网络寻址);

表示层: 对应用层数据编码和转化, 确保以一个系统应用层发送的信息 可以被另一个系统应用层识别;

2.网络协议

网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定,

常见协议

应用层:FTP,HTTP,NFS

传输层:TCP,UDP

网络层:IP,ICMP,IGMP

网络接口层:ARP,RARP

UDP协议

源端口号:发送方的端口号

目的端口号:接收方端口号

长度:UDP用户数据的长度,最小值是8(仅有首部)

校验和:检测UDP用户数据报在传输中是否有错,有错就丢弃。

TCP协议
IP协议
以太网帧协议

类型:0x800表示IP,0x806表示ARP,0x835表示RARP

CRC表示校验的四个字节。

ARP协议

根据IP地址找到MAC地址

网络通信过程

上层协议是如何使用下层协议提供的服务的呢????

其实这是通过封装实现的。应用程序数据在发送到物理网络上之前,

分用:

网络通信的过程就是对封装好协议,在网络用一个一个的以太网帧来传输,传输到后再分用,获得数据。

3.Socket套接字

所谓socket(套接字),就是对网络中不同主机上的应用进行双向通信的端点的抽象,一个套接字就是网络上进程的一端,提供了应用层进程利用网络协议交换数据的机制,套接字上联应用,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议进行交互的接口。

Linux系统采用了Socket套接字,因此,Socket接口就被广泛使用,到现在已经成为事实上的标准。与套接字相关的函数被包含在头文件sys/socket.h中。

通过上面的描述可以得知,套接字对应程序猿来说就是一套网络通信的接口,使用这套接口就可以完成网络通信。网络通信的主体主要分为两部分:客户端和服务器端。在客户端和服务器通信的时候需要频繁提到三个概念:IP、端口、通信数据,下面介绍一下需要注意的一些细节问题。

3.1 字节序

在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。

字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,也就是说对于单字符来说是没有字节序问题的,字符串是单字符的集合,因此字符串也没有字节序问题。

目前在各种体系的计算机中通常采用的字节存储机制主要有两种:Big-Endian 和 Little-Endian,下面先从字节序说起。

Little-Endian -> 主机字节序 (小端)

数据的低位字节存储到内存的低地址位, 数据的高位字节存储到内存的高地址位

我们使用的PC机,数据的存储默认使用的是小端

Big-Endian -> 网络字节序 (大端)

数据的低位字节存储到内存的高地址位, 数据的高位字节存储到内存的低地址位

套接字通信过程中操作的数据都是大端存储的,包括:接收/发送的数据、IP地址、端口。

当格式化的数据在两台使用不同字节序的主机之间直接传递时,接收端必然是错误的解释,解决问题的方法是:发送端总是把要发送的数据转换成大端字节序数据后在发送,而接受端知道对方传过来的数据总是采用大端子捷速,所以接收端可以根据自身主机进行转换。

网络字节顺序是TCP/IP协议中规定好的一种数据表示格式,它与具体的CPU类型,操作系统无关,从而保证数据在不同主机传输时能够被正确解释,网络字节序采用大端排序方式。

BSD Socket提供了封装好的转换接口,方便程序员使用,包括从主机字节序到网络字节序的转换函数:htons,htonl;从网络字节序到主机字节序的转换函数:ntohs,ntohl。

字节序函数

cpp 复制代码
#include <arpa/inet.h>
// u:unsigned
// 16: 16位, 32:32位
// h: host, 主机字节序
// n: net, 网络字节序
// s: short
// l: int

// 这套api主要用于 网络通信过程中 IP 和 端口 的 转换
// 将一个短整形从主机字节序 -> 网络字节序
uint16_t htons(uint16_t hostshort);	
// 将一个整形从主机字节序 -> 网络字节序
uint32_t htonl(uint32_t hostlong);	

// 将一个短整形从网络字节序 -> 主机字节序
uint16_t ntohs(uint16_t netshort)
// 将一个整形从网络字节序 -> 主机字节序
uint32_t ntohl(uint32_t netlong);

3.2 IP地址转换

虽然IP地址本质是一个整形数,但是在使用的过程中都是通过一个字符串来描述,下面的函数描述了如何将一个字符串类型的IP地址进行大小端转换:

cpp 复制代码
// 主机字节序的IP地址转换为网络字节序
// 主机字节序的IP地址是字符串, 网络字节序IP地址是整形
int inet_pton(int af, const char *src, void *dst); 

参数:

af: 地址族(IP地址的家族包括ipv4和ipv6)协议

AF_INET: ipv4格式的ip地址

AF_INET6: ipv6格式的ip地址

src: 传入参数, 对应要转换的点分十进制的ip地址: 192.168.1.100

dst: 传出参数, 函数调用完成, 转换得到的大端整形IP被写入到这块内存中

返回值:成功返回1,失败返回0或者-1

cpp 复制代码
#include <arpa/inet.h>
// 将大端的整形数, 转换为小端的点分十进制的IP地址        
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

参数:

af: 地址族协议

AF_INET: ipv4格式的ip地址

AF_INET6: ipv6格式的ip地址

src: 传入参数, 这个指针指向的内存中存储了大端的整形IP地址

dst: 传出参数, 存储转换得到的小端的点分十进制的IP地址

size: 修饰dst参数的, 标记dst指向的内存中最多可以存储多少个字节

返回值:

成功: 指针指向第三个参数对应的内存地址, 通过返回值也可以直接取出转换得到的IP字符串

失败: NULL

相关推荐
wayuncn几秒前
IDC机房服务器托管的费用组成
运维·服务器·github
IJ[JJ2 分钟前
学Linux的第八天
java·linux·服务器
TeYiToKu5 分钟前
笔记整理—linux驱动开发部分(8)framebuffer类设备
linux·驱动开发·笔记·嵌入式硬件·arm
Htht1115 分钟前
【Linux】常用命令
linux·服务器·网络
MXsoft6186 分钟前
监控易助力国家某办公室实现多数据中心高效监控与运维管理
大数据·运维·数据库
GGBondlctrl35 分钟前
丹摩征文活动 |【网络原理】关于HTTP的进化之HTTPS的加密原理的那些事
网络·https·非对称加密·对称加密·中间人攻击
溟洵39 分钟前
MySQl基础----Linux下数据库的密码和数据库的存储引擎(内附 实操图和手绘图 简单易懂)
linux·数据库·mysql
yfs102442 分钟前
Linux通过端口号找到程序启动路径(Ubuntu20)
linux·运维·服务器
有梦想的咕噜1 小时前
在 Ubuntu 上安装 `.deb` 软件包有几种方法
linux·运维·ubuntu
苏格拉真没有底1 小时前
docker配置代理解决不能拉镜像问题
运维·docker·容器