嵌入式学习第二十三天--网络及TCP
进程通信的方式:
同一主机
传统
system V
不同主机
网络 --- 解决不同主机间 的进程间通信
网络 (通信)
//1.物理层面 --- 联通(通路)
//卫星
2G
3G
4G
5G
星链 (千帆)
//2.逻辑层面 --- 通路(软件)
MAC os
LINUX
windows
协议
一套规则
网络协议 --- 网络通信的一套规则
通信协议 --- EDID
ARPA (阿帕网)
早期的ARPA网络使用(Network Control Protocol)NCP协议,不支持不同类型的操作系统、不同类型的计算机之间的通信,不支持纠错功能。
不同类型 计算机
不同 操作系统
无法纠错
TCP协议(Transmission Control Protocol)
控制传输过程
tcp/ip
ip地址: 作用 ---唯一标识网络上的一台主机
主机 ---网络中一台设备
ip地址 ---本质上是一个32位的数值
存储 -- 大端方式存储
ip地址组成
ip = 网络号 + 主机号
网络号 用来标识 --- 是在哪一个网络
主机号 用来标识 --- 在该网络中的哪一台计算机
www.baidu.com (网址)
|
| ---DNS解析 (Domain Name Server)
|
| ---DNS解析---ip地址 183.2.172.17
| ---[路由器]
子网掩码 ---- 用来区分 和 识别 网络号 和 主机号
连接特定的 DNS 后缀 . . . . . . . :
IPv4 地址 . . . . . . . . . . . . : 192.168.0.41
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.0.1
192 . 168 . 0 . 1
1111 1111 . 1111 1111 . 1111 1111 . 0000 0000 &
--------------------------------------------------
192 168 0 0 //网络号
协议:
OSI标准 (open system )
open system interconnect
1、OSI 模型
===》开放系统互联模型 ==》分为7层:
理想模型 ==》尚未实现
应用层
表示层 加密解密 gzip
会话层 网络断开,连接状态,keep-close keep-alive
传输层tcp udp 协议 文件 视频,音频 ipx
"12345"
网路层ip NAT
网间层 网际层
链路层 交换机 数据的格式化 帧 校验
物理层 100Mb/8 10Gbits 100MB 同轴电缆
发送 比特流 //
tcp/ip协议栈
应用层 ====》应用程序
传输层 ====》端口号tcp udp
网络层 ====》IP 地址
物理层 ====》网卡 驱动 1GB
网络编程
编程
linux操作系统
[用户空间] 应用层 //程序员实现
------------------------------------------------------
[内核空间] 传输层 [网络协议栈] //内核已经实现好的 属于网络功能
网络层
数据链路层
物理层
程序发送数据
系统调用 --- 通过系统调用来使用操作系统提供的网络功能
函数接口 --- socket
socket:
1. 操作系统提供的函数接口 //通过这个接口可以使用网络功能
2. 套接字
在使用的思路上,套接字 被抽象成了文件
特殊文件 --- 专门用来进行网络通信
文件 描述符
read
write
网络编程模型:
1.c/s 模型
client ----- server
QQ
2.b/s 模型
Brower / server //浏览器 - 服务器
3.p2p 模型
peer 2 peer //点 对 点
迅雷下载
云盘下载
c/s 模型
基于 两种传输协议实现
tcp 协议
传输层的协议 --- 控制传输过程
tcp
特点:
1.面向链接
2.可靠传输
3.字节流
应用:
登录网站 ---tcp
qq登录
udp 协议
侧重 传输效率
udp
特点:
1.无连接
2.不可靠
3.数据报
应用:
视频传输
tcp的连接:
三次握手
client -------------- server
1--连接请求-->
2<--回应------
3---确认----->
client //作为主动的角色
server //被动角色
可靠传输:
无差错
无丢失 --- 每个字节 都编号
无失序 ---
无重复 ---
tcp的编程:
流程
1.建立连接
2.数据通信
//通信模型 cs --- 打电话
//客户端
1.socket //买了个手机
2.bind (可选) // sim 卡
3.connect // 拨打电话
//服务器端
1.socket //买了个手机
2.bind // sim 卡
3.listen // 监听 --待机
4.accept // 接听
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:程序向内核提出创建一个基于内存的套接字描述符
参数:domain 地址族,PF_INET == AF_INET ==>互联网程序
PF_UNIX == AF_UNIX ==>单机程序
type 套接字类型:
SOCK_STREAM 流式套接字 ===》TCP
SOCK_DGRAM 用户数据报套接字===>UDP
SOCK_RAW 原始套接字 ===》IP
protocol 协议 ==》0 表示自动适应应用层协议。
返回值:成功 返回申请的套接字id
失败 -1;
connect
2.int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:该函数固定有客户端使用,表示从当前主机向目标
主机发起链接请求。
参数:sockfd 本地socket创建的套接子id
addr 远程目标主机的地址信息。
addrlen: 参数2的长度。
返回值:成功 0
失败 -1;
网络通信过程
QQ_A QQ_B
[用户空间] | |
-------------------socket-----------------------socket--------------
[内核空间] [传输层tcp] [传输层tcp]
|
[网络层] [网络层]
|
[数据链路层] [数据链路层]
|
[物理层] -----------------> [物理层]
网络中找到主机 ---- ip
找到主机中进程 ---- 端口号
端口号
作用: 用来标识一个进程
组成:
16位的数据
0~65535
//
1~1023 // 知名端口号
80 http
23
21
1024~50000 //系统注册的
>=50000 //动态的
ip+端口号 ==> 网络中进程的唯一地址
struct sockaddr //地址的类型
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
network byte order //网络字节序 ---大端
//字节序转换
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); //主机到网络
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong); //网络到主机
uint16_t ntohs(uint16_t netshort);
//ip地址转换
in_addr_t inet_addr(const char *cp);
"192.168.0.1"
bind
2、int bind(int sockfd, struct sockaddr *my_addr,
socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关
的文件描述符文件与参数2 指定的接口地址关联,
用于从该接口接受数据。
如果该函数在客户端调用,则表示要将数据从
参数1所在的描述符中取出并从参数2所在的接口
设备上发送出去。
注意:如果是客户端,则该函数可以省略,由默认
接口发送数据。
返回值:
成功 0
失败 -1
listen
3、 int listen(int sockfd, int backlog);
功能:在参数1所在的套接字id上监听等待链接。
参数:sockfd 套接字id
backlog 允许链接的个数。
返回值:成功 0
失败 -1;
accept
4、int accept(int sockfd, struct sockaddr *addr,
socklen_t *addrlen);
功能:从已经监听到的队列中取出有效的客户端链接并
接入到当前程序。
参数:sockfd 套接字id
addr 如果该值为NULL ,表示不论客户端是谁都接入。
如果要获取客户端信息,则事先定义变量
并传入变量地址,函数执行完毕将会将客户端
信息存储到该变量中。
addrlen: 参数2的长度,如果参数2为NULL,则该值
也为NULL;
如果参数不是NULL,&len;
一定要写成len = sizeof(struct sockaddr);
返回值:成功 返回一个用于通信的新套接字id;
从该代码之后所有通信都基于该id
失败 -1;