linux 1 网络基础
1.mac地址
网卡->物理地址 通常不会重复 虚拟网卡除外 48位 6字节
00:00:00:00:00:00
2.ip地址
标识主机Id 为虚拟的 有ipv4(32位) ipv6(64位)
分为子网ID 和主机 ID 其中的计算需要子网掩码搭配 netmask
ip中连续的1覆盖的位 子网ip
连续0覆盖的位 主机id
ip:(二进制)10.1.1.2 ->0000 1010 0000 0001 0000 0001 0000 0010
netmask->255.255.255.0->1111 1111 1111 1111 1111 1111 0000 0000
10.1.1 子网id 主机id2
网段地址:10.1.1.0
广播地址:10.1.1.255
可设置范围
1-254
3.ping
127.0.0.1->254 都是属于对本机进行联通
4.ip地址分类
5.ip netmask设置
linux中
sudo ifconfig ens33 192.168.26.33 netmask 255.255.255.0
6.桥接和net的区别
7.端口
每个程序都有一个/多个端口
作用:用来标识应用程序
port:2字节 0-65535 其中0-1023知名端口 自定义端口1024-65535
端口类似于进程号,同一时刻只能只能标志一个,可以重复使用
8.网络分层模型
物理层:双绞线的接口类型 光纤的传输速度
数据链路层:mac 负责收发数据
网络层:ip给两台主机 提供路径选择
传输层:port 区分数据递送到哪一个应用层
会话层:建立链接
表示层:解码
应用层:拿到数据
物 数 网 传 会 话 层
开发中 四层 TCP/IP模型
8.协议
规定数据传输的方式和格式
应用层协议
ftp:文件传输协议
http:超文本传输协议
省
传输层协议
tcp:传输控制协议
udp:用户数据报协议
网络层
ip:因特网互联协议
icmp:因特网控制报文协议 ping命令
ugmp:因特网管理协议】链路层
arp:地址解析协议 通过Ip找mac
rarp:反向地址解析协议 通过mac找ip
ttl->最大在网络出游走数
防止在路由器内循环
9.组包过程
圆圈内通过
10.arp通信
地址解析协议 ip找mac地址
a->广播发送信息 传给b b返回mac(局域网)
11.网络模式
B/S 网页/服务器 开发周期段
CS 客户端/服务器->客户端计算 容易开挂 开发时间长
12.socket
13.网络字节序
大小端 存储
网络传输
字节序转换
#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);
//大转小
h表示host,n表示network,l表示32位长整数,s表示16位短整数。
//如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
转大端
转小端
14.点分十进制转换
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
功能: 将点分十进制串 转成32位网络大端的数据("192.168.1.2" ==> )
参数:
af :
AF_INET IPV4
AF_INET6 IPV6
src: 点分十进制串的首地址
dst : 32位网络数据的地址
成功返回1
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
功能: 将32位大端的网络数据转成点分十进制串
参数:
af : AF_INET
src : 32位大端的网络数 地址
dst : 存储点分十进制串 地址
size : 存储点分制串数组的大小
返回值: 存储点分制串数组首地址
15.ipv4套接结构体
ipv4套接字结构体
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */ //sin_family: 协议 AF_INET
in_port_t sin_port; /* port in network byte order *///sin_portL端口
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */ // sin_addr ip地址
};
sin_family: 协议 AF_INET
sin_portL端口
sin_addr ip地址
通用套接字结构体
struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx */
char sa_data[14]; /* 14 bytes of protocol address */
};
需要强转为套接字结构体 这样可以使得结构体统一 Ipv4 和ipv6无需两个接口
socket通信流程
客户端 tcp 出错重传 每次发送数据对方都会回ACK
电话 建立链接 关闭链接
创建套接字api
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
创建套接字
参数:
domain:AF_INET
type: SOCK_STREAM 流式套接字 用于tcp通信
protocol: 0
成功返回文件描述符,失败返回-1
链接服务器
#include <sys/socket.h>
int connect(intsockfd , const struct sockaddr *addr,
socklen_t addrlen);
功能: 连接服务器
sockfd: socket套接字
addr: ipv4套接字结构体的地址
addrlen: ipv4套接字结构体的长度
客户端代码
#include<unistd.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<sys/socket.h>
int main()
{
int sock_fd;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
//链接服务器
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "172.23.128.1", &addr.sin_addr.s_addr);
connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr));
char buf[1024]="";
while (1)
{
printf("发送信息\n");
int n = read(STDIN_FILENO, buf,sizeof(buf));
write(sock_fd, buf, n);
printf("接收信息中\n");
n = read(sock_fd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, n);
}
return 0;
}
服务器代码
tcp服务器通信步骤
1.创建套接字
2.绑定
3.监听
4.提取
5.读写
6.关闭
服务器创建api
给套接字绑定固定的端口和ip
\#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
sockfd: 套接字
addr: ipv4套接字结构体地址
addrlen: ipv4套接字结构体的大小
返回值:
成功返回0 失败返回;-1
监听
listen
include <sys/socket.h>
int listen(int sockfd, int backlog);
参数:
sockfd : 套接字
backlog : 已完成连接队列和未完成连接队里数之和的最大值 128
19 accept 提取
\#include <sys/socket.h>
int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len);
如果连接队列没有新的连接,accept会阻塞
功能: 从已完成连接队列提取新的连接
参数:
socket : 套接字
address : 获取的客户端的的ip和端口信息 iPv4套接字结构体地址
address_len: iPv4套接字结构体的大小的地址
socklen_t len = sizeof(struct sockaddr );
返回值: 新的已连接套接字的文件描述符
示例
#include<unistd.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
int main()
{
//服务器代码编写
//创建套接字
int sock_fd;
int cfd_1;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
//绑定
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
inet_pton(AF_INET, "192.168.26.132", &addr.sin_addr.s_addr);
bind(sock_fd, (struct sockaddr*)&addr, sizeof(addr));
//监听
listen(sock_fd, 128);
//提取套接字
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
cfd_1=accept(sock_fd, (struct sockaddr*)&cliaddr, &len);
char buf[1024] = "";
//读写
while (1)
{
printf("发送信息\n");
bzero(buf, sizeof(buf));
int n = read(STDIN_FILENO, buf, sizeof(buf));
write(cfd_1, buf, n);
printf("读取消息如下:\n");
n = read(cfd_1, buf, sizeof(buf));
printf("%s\n", buf);
}
return 0;
}