C++学习之LINUX网络编程-套接字通信基础

目录

1.知识点概述

2.两种网络模型

3.服务器开发是什么

4.IP分类

5.IP协议

6.查看IP地址和测试主机之间是否能够通信

7.端口

8.IP和端口的使用以及域名作用

[9.OSI 七层和四层模型](#9.OSI 七层和四层模型)

10.网络协议是什么

11.数据在网络环境中发送和接受过程

12.套接字通信涉及知识点

13.字节序

14.大小端存储举例

15.IP和端口大小端转换函数

16.字符串类型的主机字节序IP转网络字节序

17.网络字节序转字符串类型的主机字节序IP地址


1.知识点概述

  • 网络设计模式

  • B/S

  • broswer - 浏览器 -> 客户端

  • html

  • css

  • js

  • server -> 服务器

  • 优势:

  • 跨平台

  • 开发成本低

  • 缺点:

  • 网络通信的时候, 必须要使用http协议

  • http / https -> 应用层协议

  • 不能在磁盘缓存或者从磁盘加载大量数据

2.两种网络模型

  • C/S

  • client -> 桌面应用程序 -> Qt

  • QQ

  • 迅雷

  • 微信

  • server -> 服务器

  • 特点:

  • 优点:

  • 使用的协议可以随意选择

  • 可以在本地缓存或者加载大量数据

  • 缺点:

  • 研发成本高

  • 在不同的平台开发不同的客户端版本

3.服务器开发是什么

服务器:

  • 硬件: 配置比较高的主机

  • 买阿里云, 百度云服务器

  • 软件:

  • 有一台主机, 主机上运行了一个进程, 这个进程可以处理网络协议, 称这台主机是一个服务器

  • nginx

  • 服务器开发:

  • 工作不是去开发web服务器

  • 我们做的工作:

  • 在一台装有服务器的主机上开发应用程序

  • 应用程序:

  • 斗地主

  • 文件服务器

4.IP分类

IP和端口

  • IP地址分类

  • 公网IP

  • 可以访问Interface, 公网IP是唯一的

  • 局域网IP

  • 小的网络, 比如一个路由器对应的家里的网段

  • 192.168.1.xxxx

  • 在这个小的网络中IP是唯一的

  • 在这个网络中的主机可以互相通信

  • 如果局域网和外网连接, 那么通过局域网IP也可以连接外网

5.IP协议

  • IP协议

  • IPV4 - `"Internet Protocol Version 4`

  • 现在应用很广泛的协议

  • IP地址的点分十进制字符串

  • `192.168.1.100`

  • 本质是一个整形数, 4字节, 32位

  • 通过3个点分成4分, 每份一个字节

  • 字节的取值范围 0-255

  • 最大的IP地址: `255.255.255.255`

  • 可用的IP地址:

  • 2的32次方 -1

  • 现在IPv4的IP地址非常不够用, 在2011年就分配完了

  • IPV6 -> `"Internet Protocol Version 6`

  • 现在应用不是很广泛, 将来主推的一种网络协议

  • 本质也是整形数, 16字节, 128bit

  • IP地址表示:

  • 分为8份, 每份2字节, 使用16进制的数字表示

  • `fe80::020c:29ff:fe40:473a`

  • ip地址的个数:

  • 2的128次方 -1

6.查看IP地址和测试主机之间是否能够通信

```shell

查看IP地址

linux

$ ifconfig

windows

$ ipconfig

测试两台主机之间是否可用通信

ping ip地址

$ ping 192.168.1.6

PING 192.168.1.6 (192.168.1.6) 56(84) bytes of data.

64 bytes from 192.168.1.6: icmp_seq=1 ttl=128 time=1.88 ms

64 bytes from 192.168.1.6: icmp_seq=2 ttl=128 time=0.678 ms

7.端口

  • 端口

```shell

1. 端口的本质?

无符号短整型数 -> unsigned short

2. 端口取值范围?

  1. 可以有多少个端口: 2的16次方

  2. 取值范围: 0 - 65535

3. 端口的作用?

定位某台主机上运行的某个进程

在电脑上运行了微信和QQ, 小明给我的的微信发消息, 电脑上的微信就收到了消息, 为什么?

  • 运行的qq和微信在启动的时候都绑定的了不同的端口

  • 小明给我的微信发送数据(点对点模型)

  • 需要知道我的IP地址 -> 定位我电脑

  • 如果定位电脑中的某一个进程呢? ---> 通过端口

8.IP和端口的使用以及域名作用

  • ip和端口的使用

```shell

通过IP定位网络环境中的主机, 通过端口定位主机上的进程

比如通过浏览器进行网络服务器访问

服务器有IP地址/域名, 服务器需要绑定端口

b/s -> 协议http -> 使用的端口是80, https协议端口-> 443

如果服务器使用的就是协议的默认端口, 访问的时候端口是可以省略不写的

http://www.baidu.com:80

https://www.baidu.com:443

http://192.168.1.100:9999

9.OSI 七层和四层模型

OSI/ISO 网络分层模型

> OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,是ISO(国际标准化组织组织)在1985年研究的网络互联模型。

```shell

上层

|

| 七层模型 四层模型

|

| 应用层

| 表示层 应用层 http/ftp/ssh/ftps

| 会话层


| 传输层 传输层 tcp / udp


| 网络层 网络层 ip -> ipv4/ipv6


| 数据链路层 网络接口层 以太网帧协议

底层 物理层

10.网络协议是什么

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

> - 数据链路层:

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

> - 规定了0和1的分包形式,确定了网络数据包的形式;

> - 网络层

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

> - 此处需要确定计算机的位置,怎么确定?IPv4,IPv6

> - 传输层

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

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

> - 会话层

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

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

> - 表示层:

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

> - 可以理解为:解决不同系统之间的通信,eg:手机上的QQ和Windows上的QQ可以通信;

> - 应用层:

> - 规定数据的传输协议

11.数据在网络环境中发送和接受过程

> - 网络协议:

>

> 计算机双方共同遵守的一组约定, 通过这个约定就可以完成连接的建立, 相互识别, 按照某种特定的数据格式进行网络通信

>

> - 发送端: 按照约定的数据格式组织数据

> - 接收端: 按照约定的数据格式解析数据

  • 常见协议

  • TCP协议 -> 传输层协议

![](assets/tcp.png)

  • UDP协议 -> 传输层协议

![](assets/udp.png)

  • IP协议 -> 网络层协议

![](assets/ip.png)

  • 以太网帧协议

![](assets/mac.png)

12.套接字通信涉及知识点

  • 数据的封装

![1558001080021](assets/1558001080021.png)

```shell

两台主机A,B

  1. A给B发送字符串 "hello, world" , 字符串不会以这种形态发送到Internet, 需要在发送之前需要封装

  2. 封装是由操作系统或者调用的API自动完成的, 程序猿无需关心

  3. 如果程序猿需要封装数据, 一般是在应用层做处理, 应用层数据可封装也可以不封装

数据 "hello, world" 在应用层 进行发送

  1. 在应用层对这个字符串封装(可选, 程序猿做的)

  2. 数据往下走-> 传输层 -> 根据协议格式打包数据 , tcp

  3. 数据往下走-> 网络层 -> 根据协议格式打包数据 , ip

  4. 数据往下走-> 网络接口层 -> 根据协议格式打包数据, 以太网帧协议

  5. 数据通过网口发送给B

B接收数据, 拆包

  1. 网络接口层 -> 根据协议格式拆包, 以太网帧协议拆开

  2. 得到了网络层的包 -> 拆包

  3. 传输层的包 -> 拆包

  4. 应用层的包

  5. 应用层如果使用协议封装了数据继续拆包, 如果没有封装得到了 "hello, world"

程序猿只需要处理应用层, 应用层以下, 不需要我们处理

13.字节序

  1. socket编程

> Socket套接字由远景研究规划局(Advanced Research Projects Agency, ARPA)资助加里福尼亚大学伯克利分校的一个研究组研发。其目的是将TCP/IP协议相关软件移植到UNIX类系统中。设计者开发了一个接口,以便应用程序能简单地调用该接口通信。这个接口不断完善,最终形成了Socket套接字。Linux系统采用了Socket套接字,因此,Socket接口就被广泛使用,到现在已经成为事实上的标准。与套接字相关的函数被包含在头文件sys/socket.h中。

![](assets/插座.png)

```c

套接字通信就是网络通信, 跟语言没有关系, 因为通信是基于协议的, 所有的编程都需要基于这些协议对数据进行处理

// 1. 套接字是什么?

  1. 套接字是一套网络通信的接口, 这个接口中封装了传输层协议( tcp / udp )

  2. 接口就是 api, 也就是一套函数

// 2. socket(插座), 套接字通信的组成部分?

  1. 服务器端, 插座的作用
  • 被动接受连接的角色, 不会主动发起连接的

  • 绑定固定IP和端口, 这样客户端才能进行连接

  1. 客户端
  • 主动发起连接的角色, 连接服务器

  • 连接服务器需要地址:

  • IP + 端口

// 3. 怎么用? -> 所有编程语言的通信流程都是固定的

  • 服务器有通信流程

  • 客户端有通信流程

14.大小端存储举例

```c

// 支持ipv4 和ipv6 格式的ip地址

#include <arpa/inet.h> // 套接字通信只需要包含这个头文件就可以了

// p-> 主机字节序的 字符串类型的IP地址

// 将主机字节序的字符串类型的IP -> 大端的整形数

int inet_pton(int af, const char *src, void *dst);

参数:

  • af: 地址族协议

  • AF_INET: 使用ipv4的网络协议

  • AF_INET6: 使用ipv6的网络协议

  • src: 主机字节序的字符串类型的IP地址, 要被转换的数据

  • dst: 传出参数, 存储了转换之后的大端的IP地址

返回值:

成功: 0

失败: -1

// 大端的整形数 --> 主机字节序的字符串类型的IP

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

参数:

  • af: 地址族协议

  • AF_INET: 使用ipv4的网络协议

  • AF_INET6: 使用ipv6的网络协议

  • src: 传入参数, 要被转换的数据, 指针指向的内存中存储了大端的IP地址(整形数)

  • dst: 传出参数, 指针指向的内存中存储了主机字节序 字符串类型的IP地址

  • size: 参数dst指向的内存的大小

返回值:

失败: NULL

成功: 指针指向函数第三个参数 dst 指向的内存

```

15.IP和端口大小端转换函数

```c

// 在写数据的时候不好用

struct sockaddr {

sa_family_t sa_family; // 地址族协议, ipv4, ipv6

char sa_data[14]; // 端口(2字节) + IP地址(4字节) + 填充(8字节)

}

typedef unsigned short uint16_t;

typedef unsigned int uint32_t;

typedef uint16_t in_port_t;

typedef uint32_t in_addr_t;

typedef unsigned short int sa_family_t;

#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))

struct in_addr

{

in_addr_t s_addr;

};

// sizeof(struct sockaddr) == sizeof(struct sockaddr_in)

struct sockaddr_in

{

sa_family_t sin_family; /* 地址族协议: AF_INET */

in_port_t sin_port; /* 端口, 2字节-> 大端 */

struct in_addr sin_addr; /* IP地址, 4字节 -> 大端 */

/* 填充 8字节 */

unsigned char sin_zero[sizeof (struct sockaddr) - sizeof(sin_family) -

sizeof (in_port_t) - sizeof (struct in_addr)];

};

```

3.4 套接字函数

16.字符串类型的主机字节序IP转网络字节序

#include <arpa/inet.h>

// 创建一个套接字(文件描述符), 用于通信或者监听都是可以的

int socket(int domain, int type, int protocol);

参数:

  • domain:

  • AF_INET: 使用ipv4的网络协议

  • AF_INET6: 使用ipv6的网络协议

  • type:

  • SOCK_STREAM: 使用流式传输协议

  • SOCK_DGRAM: 使用报式传输协议

  • protocol: 默认写0

  • 流式协议默认使用tcp

  • 报式协议默认使用udp

返回值:

成功: 返回一个文件描述符

失败: -1

// 将监听的套接字和本地IP和端口进行关联

struct sockaddr_in addr;

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数:

  • sockfd: 用于监听的套接字, 通过调用socket函数创建的

  • add: 将本地IP和端口信息初始化给该结构体, ip和端口使用大端

  • 绑定的时候服务器端一般ip地址使用 INADDR_ANY == 0

  • 0 == 0.0.0.0

  • 表示绑定本机的所有的ip地址

  • 一台主机有多个网卡 -> 多个IP地址

  • 先识别实际IP让后绑定

  • addrlen: 记录第二个参数指针指向的内存大小, sizeof(struct sockaddr)

返回值:

成功: 0

失败: -1

17.网络字节序转字符串类型的主机字节序IP地址

// 发送数据

// 写缓冲区中数据写满了, 写阻塞

ssize_t write(int fd, const void *buf, size_t len);

ssize_t send(int fd, const void *buf, size_t len, int flags);

参数:

  • fd: 通信的文件描述符

  • accept的返回值(服务器端)

  • 通过socket函数创建得到的, 通过connect初始化连接(客户端)

  • buf: 要发送的数据, 数据进入到了通信的文件描述符的写缓冲区

  • 写缓冲区数据是由内核维护管理的, 这里边有数据, 内核就会进行发送

  • len: 发送的数据的实际长度, strlen();

  • flag: 使用默认属性, 指定为0即可

返回值:

>0: 发送的实际字节数

=0: 没有发送任何数据

-1: 发送失败, 异常

// 客户端用来连接服务器

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数:

  • sockfd: 通信的文件描述符, 通过socket()得到

  • addr: 连接的服务器的IP和端口信息, 初始化该变量中, 使用网络字节序(ip+端口)

  • addrlen: 参数addr指向的内存大小

返回值:

成功: 0

失败: -1

```

相关推荐
。。。90416 分钟前
C++中,应尽可能将引用形参声明为const
开发语言·c++
云边有个稻草人18 分钟前
【C++】第九节—string类(中)——详解+代码示例
开发语言·c++·迭代器·string类·string的常用接口·string的模拟实现·string的经典例题
梁下轻语的秋缘3 小时前
实验二 VLAN 的配置与应用
网络·学习·计算机网络·智能路由器
viperrrrrrrrrr77 小时前
大数据学习(96)-Hive面试题
大数据·hive·学习
charlie1145141917 小时前
STM32F103C8T6单片机的起始点:使用GPIO输出点亮我们的第一个小灯(HAL库版本)
stm32·单片机·嵌入式硬件·学习·教程·hal库·gpio
每次的天空8 小时前
Android学习总结之算法篇五(字符串)
android·学习·算法
愚戏师9 小时前
软件工程(应试版)图形工具总结(二)
数据结构·c++·python·软件工程
owde9 小时前
顺序容器 -forward list单链表
数据结构·c++·list
矛取矛求9 小时前
C++ 标准库参考手册深度解析
java·开发语言·c++