CC BY 4.0 (除特别声明或转载文章外)
如果这篇博客帮助到你,可以请我喝一杯咖啡~
实验题目
应用层实验
实验目的
掌握应用层的基本工作原理和实现方法
实验工具
telnet
如果在命令行不能运行 telnet,则需要安装 telnet 客户端程序。
telnet 的安装方法见https://jingyan.baidu.com/article/3ea51489ba79e252e61bba97.html
在控制台可以采用鼠标右键菜单粘贴,拷贝要点击图标菜单「编辑/标记」
控制台修改缓冲区:属性/布局/屏幕缓冲区大小/高度:9999
窗口大小的宽度:200
SecureCRT
- SecureCRT 下载: http://172.18.187.9/netdisk/default.aspx?vm=17net (软件下载)SecureCRT 下载解压后直接可以使用。
- 采用 SecureCRT 中的 telnet:连接/sessions/点击右键/新建会话/协议:telnet/下一步/主机名:域名或 IP 地址 端口号:80 或 21 或 110 或 25/下一步/取名会话/完成。
- SecureCRT 设置中文显示:选项/会话选项/外观/字体:新宋体;字符集:中文 GB2312 字符编码:utf-8
- 为了可以看到更多的响应信息,需要增加缓冲区大小。
- secureCRT:会话选项/终端/仿真/回滚缓冲区:10000
- 控制台:属性/布局/屏幕缓冲区大小/高度:9000
- SecureCRT 的 SSL 配置–在 SecureCRT 中会话配置/连接/协议:Telnet/SSL
注意事项
- 截屏时注意遮盖掉自己的邮箱密码
- sina.com 的邮箱的客户端访问设置:
- QQ 邮箱需要在 Web 访问方式下开启 POP3 和 SMTP 服务才允许在客户端访问(设置/账号/开启 POP3/SMTP),否则会出现错误「454 Authentication failed, please open smtp flag first!」
要在客户端访问,QQ 邮箱可能还会要求设置独立密码,即可以设置与 QQ 登录不同的密码。QQ Web 邮箱查看源码的方法:
- QQ 邮箱编程必须使用 Telnet/SSL 协议(加密模式):
- SecureCRT 的 SSL 配置–在 SecureCRT 中会话配置/连接/协议:Telnet/SSL
- QQ 邮箱的接收邮件服务器:pop.qq.com,端口号为 995
- QQ 邮箱的发送邮件服务器:smtp.qq.com,端口号为 465
- 客户端登录的用户名为 QQ 号的 base64 编码
- 客户端登录的密码也采用 base64 编码
实验内容
先认真阅读课件「Chapter2-applicaton-layer.pdf」,再完成下面内容。注意:协议标准可以查阅 RFC;选取的内容不要与课件相同;响应内容太长时自己选取截取前后部分以及其中重点部分。
参考视频:http://172.18.187.9/video/
使用自己编写的 TcpClient,采用聊天程序的客户端。该客户端采用两个进程实现:一个输入和发送线程,一个接收线程。(选做)如果不自己编写 TcpClient,可以尝试使用老师给的 TcpClient.exe 完成步骤一~步骤四,如果不愿意尝试,可以使用 telnet 来完成实验。 源代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <ws2tcpip.h> //gcc Client.c -lWs2_32 -o Client
#pragma comment(lib, "ws2_32.lib")
#define BUFLEN 20 << 20 //20MB
int finish = 0;
unsigned __stdcall recvMessage(SOCKET *p)
{
static char buf[BUFLEN];
while (!finish)
{
int c = recv(*p, buf, BUFLEN, 0);
if (c > 0)
buf[c] = 0, printf("%s", buf);
else if (!c)
printf("Recv connect closed.\n"), finish = 1;
else if (c == SOCKET_ERROR)
printf("Recv Error:\n%d\n", GetLastError());
}
}
int main(int argc, char **argv)
{
if (argc < 3)
return 0;
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 0), &wsadata);
struct addrinfo *host;
getaddrinfo(argv[1], argv[2], NULL, &host);
SOCKET sock = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
if (connect(sock, host->ai_addr, host->ai_addrlen))
printf("Connect unsuccessfully.\n");
HANDLE h = _beginthreadex(NULL, 0, &recvMessage, &sock, 0, NULL);
static char buf[BUFLEN];
while (!finish)
{
int len = 0;
for (printf("Input the message(end by EOF, Ctrl+Z in Windows) :\n"); !finish && gets(buf + len);)
buf[len += strlen(buf + len)] = '\r', buf[++len] = '\n', buf[++len] = 0;
int c = send(sock, buf, len, 0);
if (!c)
printf("Send connect closed.\n"), finish = 1;
else if (c == SOCKET_ERROR)
printf("Send Error:\n%d\n", GetLastError());
}
CloseHandle(h);
closesocket(sock);
freeaddrinfo(host);
WSACleanup();
getch();
}
HTTP 协议
看完 HTTP 协议的课件后完成以下实验:
从学院网站(sdcs.sysu.edu.cn)找一网页下载。
下载一个老师的个人主页。
http 请求:
1
2
GET /content/2564.html HTTP/1.1
Host: sdcs.sysu.edu.cn
http 响应:
从学院网站(sdcs.sysu.edu.cn)找一图片下载。
天河二号镇楼。 http 请求:
1
2
GET /sites/sdcs.live1.dpcms8.sysu.edu.cn/files/styles/slideshow/public/slideshow/frontpic2.jpg HTTP/1.1
Host: sdcs.sysu.edu.cn
http 响应:
在 http 请求的头部行中加入If-Modified-Since: Fri, 16 Jan 2019 13:22:17 GMT
从学院网站下载(2)的图片。
http 请求:
1
2
3
GET /sites/sdcs.live1.dpcms8.sysu.edu.cn/files/styles/slideshow/public/slideshow/frontpic2.jpg HTTP/1.1
If-Modified-Since: Fri, 16 Jan 2019 13:22:17 GMT
Host: sdcs.sysu.edu.cn
http 响应:
用流水线方式实现前面(1)(2),即把它们的请求拷贝到一起后发送出去(可能太长,第一部分可以只有看到末尾)。
http 请求:
1
2
3
4
5
GET /content/2564.html HTTP/1.1
Host: sdcs.sysu.edu.cn
GET /sites/sdcs.live1.dpcms8.sysu.edu.cn/files/styles/slideshow/public/slideshow/frontpic2.jpg HTTP/1.1
Host: sdcs.sysu.edu.cn
http 响应:
FTP 协议
看完 FTP 协议的课件后完成以下实验(测试服务器上的目录结构和文件见「参考资料」): FTP 服务器:IP 地址为 172.18.187.10,端口号为 21 (用户名:abc,密码:123666)
上传用学号命名的一个文本文件(学号.txt)
控制连接的请求响应信息:
user abc
pass 123666
pasv
stor 17341163.txt
数据连接的截屏:
查看当前目录内容(太多则选择一些),并标注出(1)中自己上传的文件
控制连接的请求响应信息:
pasv
list
数据连接的截屏:
下载(1)中自己上传的文本文件
控制连接的请求响应信息:
pasv
type I
retr 17341163.txt
数据连接的截屏:
下载/ebook 下的一个二进制文件(例如,.pdf 文件)
控制连接的请求响应信息:
pasv
type I
retr \ebook\ftp.pdf
数据连接的截屏:
采用断点续传下载一个/text 下的一个文本文件的一部分
控制连接的请求响应信息:
pasv
rest 20
retr \text\123456.txt
数据连接的截屏:
编写一个程序(聊天程序的客户端),用 FTP 协议下载指定文件(选做)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <ws2tcpip.h> //gcc ftpDownload.c -lWs2_32 -o ftpDownload
#pragma comment(lib, "ws2_32.lib")
#define BUFLEN 20 << 20 //20MB
int finish = 0;
int main(int argc, char **argv)
{
if (argc < 4)
return 0;
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 0), &wsadata);
struct addrinfo *host;
getaddrinfo(argv[1], argv[2], NULL, &host);
SOCKET sock = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
if (connect(sock, host->ai_addr, host->ai_addrlen))
printf("Connect unsuccessfully.\n");
static char buf[BUFLEN];
int c = recv(sock, buf, BUFLEN, 0);
if (c > 0)
buf[c] = 0, fwrite(buf, sizeof(*buf), c, fopen(argv[3], "wb"));
else if (!c)
printf("Recv connect closed.\n"), finish = 1;
else if (c == SOCKET_ERROR)
printf("Recv Error:\n%d\n", GetLastError());
closesocket(sock);
freeaddrinfo(host);
WSACleanup();
getch();
}
SMTP 协议
邮箱 [email protected] 的用户名 zsusender3,密码:123456Aa
老师的邮箱因为被太多人发了邮件所以被封了…所以这里使用我自己的邮箱了。使用 qq 邮箱的时候要用授权码代替密码登录。
此外,由于使用了自己写的客户端,不支持 SSL,因此需要连接的是 QQ 邮箱smtp.qq.com
的25
号端口了。
看完 SMTP 协议的课件后做以下实验:
通过 [email protected] 发一封没有附件的邮件到你的邮箱。
请求和响应信息:
HELO 942759535
AUTH LOGIN
**********
**********
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Date: Tue, 25 Mar 2019 14:24:01 +0800
From: "WuK"<[email protected]>
To: "WuK"<[email protected]>
Subject: SDCS 17 isszym
This is a SDCS message in MIME format. Hello! SDCS 17 from isszym
.
QUIT
通过 [email protected] 发一封带附件(二进制文件)的邮件(MIME.txt)到你的邮箱。参考课件「MIME.pdf」和观看 MIME 的视频。
请求和响应信息:
HELO 942759535
AUTH LOGIN
**********
**********
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
X-QQ-FEAT: 7sdUmzD4oweFIsey27zpBk4l3+YhTr3obqJMN17W9QW8odzFKBJBpahQ2QmzM
BJeAZHPq1ECvrJ84Hb+axWE1UG7GMIdG62vK3iWwEjy1t/VPhXUc7alElXj5pGoS0SW7Pyb
VcEiB+T1hzoCsT/BuyKatavpoynp2t752fFOHyElV6X0XqqW0SwBdVpN6F8bRlyLSlPGwDF
eWhrWkQiprLVrSqO8quTiT3UEoUEnSEMCWe7EZt1poRy1geCSPyPoLCIUvyi2AmYHi5SzRA
FmswX+wEHO4+Ph
X-QQ-SSF: 000100000000004000000000000000X
X-HAS-ATTACH: no
X-QQ-BUSINESS-ORIGIN: 2
X-Originating-IP: 120.236.248.201
X-QQ-STYLE:
X-QQ-mid: webmail518t1555039835t5547251
From: "=?utf-8?B?V3VL?=" <[email protected]>
To: "=?utf-8?B?d3Uua2Fu?=" <[email protected]>
Subject: homework
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_NextPart_5CB0065B_09778B80_1EF3FF40"
Content-Transfer-Encoding: 8Bit
Date: Fri, 12 Apr 2019 11:30:35 +0800
X-Priority: 3
Message-ID: <[email protected]>
X-QQ-MIME: TCMime 1.0 by Tencent
X-Mailer: QQMail 2.x
X-QQ-Mailer: QQMail 2.x
This is a multi-part message in MIME format.
------=_NextPart_5CB0065B_09778B80_1EF3FF40
Content-Type: multipart/alternative;
boundary="----=_NextPart_5CB0065B_09778B80_5050EE5C";
------=_NextPart_5CB0065B_09778B80_5050EE5C
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: base64
c2VuZCBhIGZpbGU=
------=_NextPart_5CB0065B_09778B80_5050EE5C
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: base64
PGRpdj5zZW5kIGEgZmlsZTwvZGl2Pg==
------=_NextPart_5CB0065B_09778B80_5050EE5C--
------=_NextPart_5CB0065B_09778B80_1EF3FF40
Content-Type: application/octet-stream;
charset="utf-8";
name="=?utf-8?B?5paw5bu65paH5pys5paH5qGjLnR4dA==?="
Content-Disposition: attachment; filename="=?utf-8?B?5paw5bu65paH5pys5paH5qGjLnR4dA==?="
Content-Transfer-Encoding: base64
aGkhDQo=
------=_NextPart_5CB0065B_09778B80_1EF3FF40--
.
成功收到,欧耶。
(选做)从你的邮箱发一份邮件到同学的邮箱。QQ 邮箱见【注意事项】。
请求和响应信息:
HELO 942759535
AUTH LOGIN
**********
**********
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>
DATA
Date: Fri, 12 Fri 2019 11:00:00 +0800
From: "WuK"<[email protected]>
To: "PengJX"<[email protected]>
Subject: Deep♂Dark♂Fantasy
Oh♂That's♂good
.
基友收到邮件截图如下,表示
POP3 协议
邮箱 [email protected] 的用户名 zsureceiver3,密码:123456Aa
同上,这里使用了自己的 QQ 邮箱。尝试使用自己写的客户端,然而连接上服务器之后由于没有 SSL 被服务器拒绝了。因此这一部分使用 SecureCRT 完成。
看完 POP3 协议的课件后做以下实验:
查看 [email protected] 中每个邮件大小。
请求和响应信息:
取回 [email protected] 最后一封邮件的邮件唯一标识符。
请求和响应信息:
取回 [email protected] 最后一封邮件。
请求和响应信息:
取回三(1)中发到你邮箱的邮件。QQ 邮件见【注意事项】。
请求和响应信息:
实验体会
做完了应用层的实验,对大千网络背后的运行机理开始有了一些理解了,原来看似缤纷的因特网背后是由这些容易理解的协议罢了。并且,自己写的并不怎么复杂的客户端程序,经由这些简单的协议 就可以直接与现有的互联网产生交互,还是非常有意思的。