网络:
不同主机间的通信问题
实现网络通信
- 物理层面 有一个 信息通路 (有线 ;无线 ;5G;4G;星链 )
- 软件层面(逻辑层面) 也需要 一个通路
网络编程
Open System Interconnect (OSI网络模型)
为了解决不同体系结构的网络的互联问题,国际标准化组织ISO(注意不要与OSI搞混)于1981年制定了开放系统互连参考模型
(Open System Interconnection Reference Model,OSI/RM)
osi参考模型
7. 应用层 | 直接获取要收发的数据 |
6. 表示层 | 规定了 传输数据的格式 和 方式 //加密 |
5. 会话层 | 处理一次会话过程 |
4. 传输层 | 传输控制层,控制传输过程,保证数据完整和可靠 |
3. 网络层 (网际层) | 用于解决 网络 与 网络之间 数据传输 //数据包 |
2. 数据链路层 | 规定了传输数据的格式 //帧数据 控制传输过程可靠 |
1. 物理层 | 规定了物理层面的电气特性及相关机械特性 物理层面数据的传输 --- 一位一位二进制数据 //比特流 |
实际应用到的是 tcp/ip 模型 ;每个层次中,都有自己的一套规范 (协议)
操作系统角度:
(1)用户层 应用层 ---------程序员
(2)内核层 传输层----------这些层次 操作系统已经实现
网络层 //tcp/ip 协议 栈 (网络协议栈)
数据链路层
物理层
1. IP
是网络中主机的唯一标识,它由网络地址和主机号组成。网络地址是子网的唯一标识,类似于电话号码的区号;主机号是子网内每台主机的编号。在现在(IPv4)的网络中,IP地址是32bit的二进制数,采用大端字节序:
(1)表示方法(点分十进制)
直接使用二进制数,不容易记忆,为了方便记忆,将32位二进制码划分为4个字节,每个字节转化成相应的十进制数,字节之间用“.”来分隔,这种表示方法,称之为“点分十进制表示法”。
例:192 .168 .1 .1
11000000 10101000 00000001 00000001
(2)分类
(3)范围
类型 | 范围 | 用途 | |
A类 | 0.x.x.x---127.x.x.x.x | 10.x.x.x | 私网(局域网)地址 |
127.x.x.x | 环回网络地址 | ||
其他 | 大型主干网地址 | ||
B类 | 128.x.x.x - 191.x.x.x | 172.16.x.x - 172.31.x.x | 私网(局域网)地址 |
169.254.x.x | 表示没有找到DHCP服务器 | ||
其他 | 主干(城市)网地址 | ||
C类 | 192.x.x.x - 223.x.x.x | 192.168.x.x | 私网(局域网)地址 |
D类 | 组播地址 | ||
E类 | 保留 |
注意:主机号为0的IP地址是网络地址,主机号为255的地址是广播地址。
2. ip地址的组成:
网络号 + 主机号
- 网络号 ---表示所处的网络
- 主机号 ---表示能容纳的主机
2. 端口号
用来表示主机中某一个具体(进行网络通信)进程 ;16位数值(unsigned short ) //0~65535 (65536个数)标示一个进程
ip+端口:进程在网络的 地址
TCP和 UDP 的端口号是独立的
(1) 作用:
- 唯一的标识一个进程
- 每一个应用程序进程有一个端口号,
- 通讯时区分数据包属于哪个应用程序进程
(2) 分类
端口号一般由IANA (Internet Assigned NumbersAuthority) 管理
1)众所周知端口:
1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)
知名端口号(已经分配给标准应用服务软件)
如:
http协议用到的端口号 80
2) 已登记端口:
1024~49151
注册端口号(非标准应用服务软件的软件可以申请的端口号范围)
3)动态或私有端口://50000 以上的端口号
49152~65535 动态分配的端口号(系统动态分配给应用程序使用的)
(3) 长度
2字节(16bit)
3.掩码
mask // 遮住 (255.255.255.0)
获取IP地址中的网络地址和主机地址:
网络编程:
一、TCP(即传输控制协议):
一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、数据无失序、数据无重复到达的通信)
适用情况:
- 适合于对传输质量要求较高,以及传输大量数据的通信。
- 在需要可靠数据传输的场合,通常使用TCP协议
- QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议
tcp协议特点:
- 面向连接 //类似打电话通话之前 ,必须先打通
- 可靠传输 //保证数据准确可靠 (tcp协议机制 里面的功能 )
- 面向字节流程
二、UDP(User Datagram Protocol)
用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。
适用情况:
- 发送小尺寸数据(如对DNS服务器进行IP地址查询时)
- 在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
- 适合于广播/组播式通信中。
- MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
- 流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输
UDP协议特点:
- 不可靠
- 无连接
- 数据报
三、编程:
编程模型
c/s client server 客户端,服务器模型 --- 专用客户端
b/s browser server 浏览器,服务器模型 --- 通用的客户端
p2p peer to peer 点对点传输
1.基于UDP c/s通信模型:
(1)client ---客户端 --- 角色 --- 主动的角色
socket:
- 一种特殊的文件 --- 专门用于网络通信(不同主机间的进程)
- socket 编程接口 --- socket 函数
- 提供了一个可以访问 操作系统 网络功能的接口
sendto :发数据
(2)server --- 服务器端 --角色 --- 被动的角色
socket :
recvfrom //接收数据
编程函数:
1.socket函数:
int socket(int domain, int type, int protocol);
(1)功能:程序向内核提出创建一个基于内存的套接字描述符
(2)参数:domain:域 (范围) ---socket 用于什么范围的通信,ipv4 / ipv6 ;
domain 地址族, PF_INET == AF_INET ==>互联网程序
PF_UNIX == AF_UNIX ==>单机程序
type :套接字类型:
- SOCK_STREAM 流式套接字 ===》TCP
- SOCK_DGRAM 用户数据报套接字===>UDP
- SOCK_RAW 原始套接字 ===》IP
protocol 协议 ==》0 表示自动适应应用层协议。
(3)返回值:成功:返回申请的套接字文件描述符 ;失败: -1
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int main(int argc, const char *argv[])
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("socket fail");
return -1;
}
printf("fd = %d\n",fd);
return 0;
}
2.sendto函数:
ssize_t sendto( int sockfd, //用于通信的socket对应的fd
const void *buf, //表示要发送的数据所在的一块空间
size_t len, //表示发送的字节数
int flags, //0 --- 默认const struct sockaddr *dest_addr, //表示 要发送到的 地址 (网络地址 ip+端口号 )
socklen_t addrlen); //表示dest_addr 这个参数的长度
返回值:成功发送出去的字节的数 ;失败: -1 ;
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <string.h>
int main(int argc, const char *argv[])
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("socket fail");
return -1;
}
printf("fd = %d\n",fd);
char buf[1024] = "hello udp\n";
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.1.149");
sendto(fd,buf,strlen(buf)+1,0,(const struct sockaddr *)&seraddr,sizeof(seraddr));
return 0;
}
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 IP */
};/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};