更新源
cd /etc/apt/
sudo cp sources.list sources.list.save 将原镜像备份
sudo vim sources.list 将原镜像修改成阿里源/清华源,如所述
阿里源
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
清华源
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
上述操作完毕后,保存退出,执行下列:
sudo apt-get update
1. wireshark使用
1. 安装
1) wireshark的官方下载网站:www.wireshark.org/
2) Linux sudo apt install wireshark
3) 启动sudo wireshark
设置中文 Edit->Preferences->Appaerance->Language->Chinese
2. wireshark 抓包
1.
开始抓包
开始界面
1.
wireshark是捕获机器上的某一块网卡的网络包,当你的机器上有多块网卡的时候,你需要选择一个网卡。
2.
双击需要的网卡,开始抓包
1.
Wireshark 窗口介绍
3. wireshark与对应的OSI七层模型
服务器和客户端的代码不能都运行在ubuntu,因为wireshark抓的是流经真实网卡的数据包。
若将服务器客户端都运行在ubuntu,数据直接经过虚拟网卡通信,而不会经过真实网卡。
2. 包头分析
2.1 以太网头
以太网中封装了源mac地址以及目的mac地址,还有ip类型,以太网又称之为mac头
0X0800 只接收发往本机的mac的ip类型的数据帧
0X0806 只接收发往本机的ARP类型的数据帧
0x8035 只接受发往本机的RARP类型的数据帧
0X0003 接收发往本机的MAC所有类型:ip,arp,rarp数据帧,接收从本机发出去的数据帧,
混杂模式打开的情况下,会接收到非发往本地的MAC数据帧
2.2 IP头
IP头中需要掌握用于拆包的部分:id flags fregment_offset
两个IP地址:源IP与目的IP地址。
TTL:time to live, 指定数据帧可以最多经过几个路由器。当数据帧被目标方接收后,TTL清除为0.
Linux TTL:64 Winodws:TTL 128
2.3 UDP头
2.4 TCP头
Seq:序列号,占4个字节,用于给数据段进行编号的。所有非应答包的数据段,都有seq。
Ack:应答号,用于应答非应答包(握手包,挥手包,数据包)。告诉对方下一次从这个seq编号发送数据包。
SYN:握手包,连接的时候产生的包
FIN:挥手包,断开连接产生的包
PSH:数据包,传输数据时候产生的包
ACK:应答包
PSH Ack = Seq+len;
SYN FIN Ack = Seq+1;
2.5 三次握手
三次握手的发起方,肯定是客户端
1.
第一次握手:客户端发送SYN包(SYN=1, seq=0)给服务器,并进入SYN_SENT状态,等待服务器返回确认包。
2.
第二次握手:服务器接收到SYN包,确认客户端的SYN,发送ACK包(ACK=1 , ack=1),同时发送一个SYN包(SYN=1, seq=0),并进入SYN_RCVD状态。
3.
第三次握手:客户端接收到服务器的SYN包,以及ACK包,进入establish状态,同时向服务器发送ACK包(ACK=1, ack=1)。此时三次握手包发送完毕,服务器也进入establish状态
2.6 四次挥手
四次挥手的发起方可能是服务器,也可能是客户端
1.
第一次挥手,主动关闭方发送一个FIN包(FIN=1, seq = u)给被动方,进入FIN_WAIT_1状态;
2.
第二次挥手:被动方接收到FIN包,给主动方发送一个ACK包(ACK=1, ack=u+1);并进入CLOKSE_WAIT状态。主动方接受到ACK包后,进入FIN_WAIT_2状态。如果有数据没有发送完毕,则继续发送,直到发送完毕为止;
3.
第三次挥手:被动方发送一个FIN包(FIN=1, seq=w),进入LAST_ACK状态.
4.
第四次挥手:主动关闭方收到FIN包,回复一个ACK包(ACK=1, ack=w+1)。被动关闭方收到主动关闭方的ACK后关闭连接。
三、何为HTTP
1> Hyper Text Transfer Protocol(超文本传输协议),用于万维网(WWW:world wide web)进行超文本(html文档)信息的传送协议
2> 该协议属于应用层协议,传输层是使用TCP实现的
3> http是基于BS模型,即浏览器服务器模型,主要完成的是客户端请求端和服务器相应端
4> 实现模型
四、超文本文档HTML
1> Hypertext Markup Language 超文本标记语言,属于标签式语言,能够被浏览器所识别
2> 案例文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>欢迎来到我的主页</title>
</head>
<body align="center">
<h1 >欢迎欢迎来的我的主页</h1>
姓名:<input type="text">
年龄:<input type="password"><br><br>
留言 <textarea name="" id=""></textarea><br>
<input type="button" value="提交">
<input type="button" value="取消">
</body>
</html>
#include <string.h>
char *strtok(char *str, const char *delim);
功能:通过指定的字符串,将前面的字符串进行分割
参数1:要被分割的字符串
参数2:分隔符
返回值:成功返回分割出来的第一个字符串的起始地址,后续如果想要后面的字符串,参数1填NULL即可
#include <unistd.h>
int access(const char *pathname, int mode);
功能:判断给定的文件是否具有某个功能
参数1:要判断的文件
参数2:要判断的权限
R_OK:读权限
W_OK:写权限
X_OK:可执行权限
F_OK:是否存在
返回值:如果要判断的权限全都存在,则返回0,否则返回-1并置位错误码
五、客户端请求
5.1 请求首部
1> 任何一个http请求都由三部分组成:请求首部、请求主体、请求数据
2> 对于客户端请求协议包而言,一般没有请求数据,具体格式如下
3> 方法:
GET:表示发送请求数据(常用)
POST:应答数据(常用)
DELETE:删除文档
PUT:上传文件
4> 需要对发来的请求进行解析,需要获取请求头部部分的方法以及url以便于相应
#include<myhead.h>
#define SER_PORT 80 //服务器端口号
#define SER_IP "192.168.0.133" //服务器ip地址
int get_one_line(int newfd, char msg[])
{
char buf = '\0'; //读取消息
int i = 0; //填充数组
while(1)
{
int res = recv(newfd, &buf, 1, 0);
if(res == 0)
{
break;
}else if (res== 1)
{
if(buf=='\n')
{
break;
}else
{
msg[i] = buf;
i++; //填充下一个
}
}else
{
perror("recv error");
return -1;
}
}
msg[i] = '\0';
}
int main(int argc, const char *argv[])
{
//1、创建套接字
int sfd = socket(AF_INET, SOCK_STREAM, 0);
//参数1:表示ipv4的网络通信
//参数2:表示使用的是TCP通信方式
//参数3:表示默认使用一个协议
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success, sfd = %d\n", sfd); //3
//将端口号快速重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
printf("端口号快速重用成功\n");
//2、为套接字绑定ip地址和端口号
//2.1 填充地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; //通信域
sin.sin_port = htons(SER_PORT); //端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); //ip地址
//2.2 绑定工作
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、将套接字设置成被动监听状态
if(listen(sfd, 128)==-1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
//4、阻塞等待客户端的连接请求
//4.1 定义变量用于接收客户端的信息
struct sockaddr_in cin; //用于接收地址信息
socklen_t addrlen = sizeof(cin); //用于接收长度
while(1)
{
//4.2 接收连接
int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen) ;
if(newfd == -1)
{
perror("accept error");
return -1;
}
printf("[%s:%d]: 已成功连接一个客户端\n", \
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
//5、数据收发
char buf[128] = "";
//接收请求头部
get_one_line(newfd, buf); //获取到请求行
//printf("buf = %s\n", buf);
//获取请求请求方法
char mathod[5] = "";
strcpy(mathod, strtok(buf, " ")); //将分割下的第一个串放入到mathod中
char url[50] = "";
strcpy(url, strtok(NULL, " "));
//printf("mathod = %s, url = %s\n", mathod, url);
//判断是否为GET方法
if(strcmp(mathod, "GET") == 0)
{
//说明要进行get请求,完成响应工作
//重组url
snprintf(url, "./htmls%s", url);
//判断要访问的文件是否存在
if(access(url, F_OK) ==-1)
{
//返回一个响应为NOT FOND的网页
//do_notfond(newfd);
return -1;
}else
{
//给出响应
//do_response(newfd);
}
}else
{
//非法请求
//do_illigal(newfd);
}
}
//6、关闭监听
close(sfd);
return 0;
}
5.2 响应首部
1> 响应首部也是由三部分组成,分别是响应头、响应主体、响应数据
2> 对于响应首部而言,必须由响应数据
3> 常见的响应代号
http的响应代号:1XX (信息状态错误) 2XX(成功) 、3XX(重定向状态码)、4XX(客户端错误)、5XX(服务器出错)
100:表示服务器已经结束请求头,并且客户的响应发送数据请求主体出错
200:OK
201:表示请求已经成功,服务器返回了主体部分
202:表示请求已经成功,并且服务器上创建了新的资源
404:NOT FOUND
500:服务器内核出错
503:服务器网关出错