0%

计算机网络实验三_应用层实验

应用层实验

实验目的

掌握应用层的基本工作原理和实现方法

实验工具

telnet,WSL

实验内容

HTTP协议的实验

从学校网站(www.sysu.edu.cn)找一个网页下载

http请求:

1
2
3
GET /2012/cn/index.htm HTTP/1.1
Connection: keep-alive
Host: www.sysu.edu.cn
1
2
GET /2012/cn/index.htm HTTP/1.1
Host: www.sysu.edu.cn

http响应:

image.png

从学校网站(www.sysu.edu.cn)找一个图片下载

http请求:

1
2
GET /2012/images/content/2020-02/20200202145357635528.jpg HTTP/1.1
Host: www.sysu.edu.cn

http响应:
image.png

在http请求的头部行中加入If-Modified-Since: Sat, 16 May 2020 14:57:17 GMT从学校网站下载(2)的图片

http请求:

1
2
3
GET /2012/images/content/2020-02/20200202145357635528.jpg HTTP/1.1
If-Modified-Since: Sat, 16 May 2020 14:57:17 GMT
Host: www.sysu.edu.cn

http响应:
image.png
没有修改

用流水线方式实现前面(1)(2),即把它们的请求拷贝到一起后发送出去(可能太长,第一部分可以只有看到末尾)。注意:connection都要是keep-alive

http请求:

1
2
3
4
5
6
7
GET /2012/cn/index.htm HTTP/1.1
Connection: keep-alive
Host: www.sysu.edu.cn

GET /2012/images/content/2020-02/20200202145357635528.jpg HTTP/1.1
Connection: keep-alive
Host: www.sysu.edu.cn

http响应:

image.png
image.png

用(1)的地址取回网页的一部分(100-200,400-)

http请求:

1
2
3
4
GET /2012/cn/index.htm HTTP/1.1
Connection: keep-alive
Range:bytes=100-200,400-
Host: www.sysu.edu.cn

http响应:
image.png

FTP协议的实验

FTP服务器:IP地址为103.26.79.35,端口号为 21 (用户名:net,密码:123456)

上传用学号命名的一个文本文件(学号.txt)

控制连接的请求响应信息:
image.png

数据连接的截屏:
image.png

查看当前目录内容(太多则选择一些),并标注出(1)中自己上传的文件

控制连接的请求响应信息:
image.png
数据连接的截屏:
image.png

下载(1)中自己上传的文本文件

控制连接的请求响应信息:
image.png
数据连接的截屏:
image.png

下载/ebook下的一个二进制文件(例如,.pdf文件)

控制连接的请求响应信息:
image.png
数据连接的截屏:
image.png

采用断点续传下载一个/text下的一个文本文件的一部分

控制连接的请求响应信息:
image.png
数据连接的截屏:
image.png

分两次上传一个文本文件 (使用APPE命令)

控制连接的请求响应信息:
image.png

第一次数据连接的截屏
image.png
第一次ftp目录的截屏(包含上传文件):
image.png
第二次数据连接的截屏
image.png
第二次ftp目录的截屏(包含上传文件):
image.png
修改时间改变了。

SMTP协议的实验

通过我的QQ邮箱发一封没有附件的邮件到我的中大邮箱

请求和响应信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HELO 1347453756
AUTH LOGIN
*******
*******
MAIL FROM:<1347453756@qq.com>
RCPT TO:<zhangjr35@mail2.sysu.edu.cn>
data
Date:Sat, 16 May 2020 21:52:50 +0800
From: "1347453756" <1347453756@qq.com>
To: "zhangjr35"<zhangjr35@sysu.edu.cn>
Subject: I am zjr
This a mail from zjr to zjr
.
QUIT

image.png
打开中大邮箱,发现确实可以收到:
image.png

通过我的QQ邮箱发一封带附件(二进制文件)的邮件(MIME.txt)到我的中大邮箱

请求和响应信息:

1
2
3
4
5
6
HELO 1347453756
AUTH LOGIN
******
******
MAIL FROM:<1347453756@qq.com>
RCPT TO:<zhangjr35@mail2.sysu.edu.cn>

邮件内容:
image.png
收到结果:
image.png

通过中大邮箱发送另一个带附件的邮件给QQ邮箱。可以先给你自己发一封带附件的邮件,再通过查看源码截取该响应报文的一部分,参见MIME.txt

找了半天也没有找到查看源码的地方在哪。。。。。。只能放弃了。

从你的邮箱发一份邮件到同学的邮箱

请求和响应信息:

1
2
3
4
5
6
HELO 1347453756
AUTH LOGIN
******
******
MAIL FROM:<1347453756@qq.com>
RCPT TO:zhanghb55@mail2.sysu.edu.cn

邮件内容:

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
data
Date: Thu, 17 Apr 2014 20:30:07 +0800
From: =?utf-8?B?zjr?= <1347453756@qq.com>
To: zhanghb55 <zhanghb55@mail2.sysu.edu.cn>
Subject: hbnb
Mime-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_001_NextPart061116676577_=----"

This is a multi-part message in MIME format.

------=_001_NextPart061116676577_=----
Content-Type: multipart/alternative;
boundary="----=_002_NextPart640832068374_=----"


------=_002_NextPart640832068374_=----
Content-Type: text/plain;charset="GB2312"
Content-Transfer-Encoding: base64

aGJuYmhibmI=

------=_002_NextPart640832068374_=------

------=_001_NextPart061116676577_=------
.

实验结果:
image.png
好像时间不对。。。为了避免麻烦同学就没改了。

POP3协议

查看我的QQ邮箱中每个邮件大小

请求和响应信息:
image.png

取回我的QQ邮箱的最后一封邮件的邮件唯一标识符

请求和响应信息:
用 UIDL 命令即可
image.png

取回zsureceiver5@sina.com最后一封邮件

请求和响应信息:
用RETR命令即可
image.png

取回三(1)中发到你邮箱的邮件

请求和响应信息:
先用list命令看一下有多少封,取出最后一封即可。
image.png

五、mytelent源代码

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* client2.c */
#include<netdb.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <error.h>
#include <pthread.h>
#define BUFLEN 20000 // 缓冲区大小

void input(char* buf){
fgets(buf,BUFLEN,stdin);
int len=strlen(buf);
buf[len-1]='\r',buf[len]='\n',buf[++len]='\0';
}

void* client_recv(void* in){
int my_sock=(long)in;
char* buf=(char*)malloc((BUFLEN+1)*sizeof(char));
while(1){
int c1=recv(my_sock,buf,BUFSIZ,0);
if(c1==0){
return NULL;
}
buf[c1]='\0';
printf("%s\n",buf);
}
}


int main(int argc,char* argv[]){
char* ptr,**pptr;
struct hostent* hptr;
char str[32];
ptr=argv[1];
if((hptr=gethostbyname(ptr))==NULL){
perror("gethostbyname");
return -1;
}
pptr=hptr->h_addr_list;
const char* host=inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str));
printf("%s",host);
char *service = argv[2]; /* server port to connect */
struct sockaddr_in sin; /* an Internet endpoint address */
char buf[BUFLEN+1]; /* buffer for one line of text */
int sock; /* socket descriptor */
int cc; /* recv character count */
pthread_t thread_handle;
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //创建套接字,参数:因特网协议簇(family),流套接字,TCP协议
//返回:要监听套接字的描述符或INVALID_SOCKET
memset(&sin, 0, sizeof(sin)); // 从&sin开始的长度为sizeof(sin)的内存清0
sin.sin_family = AF_INET; // 因特网地址簇
sin.sin_addr.s_addr = inet_addr(host);
// printf("%d\n",sin.sin_addr.s_addr); // 设置服务器IP地址(32位)
sin.sin_port = htons((unsigned short)atoi(service)); // 设置服务器端口号
int ret=connect(sock, (struct sockaddr *)&sin, sizeof(sin)); // 连接到服务器,第二个参数指向存放服务器地址的结构,第三个参数为该结构的大小,返回值为0时表示无错误发生,
pthread_create(&thread_handle,NULL,client_recv,(void*)sock);
while(1){
input(buf);
if(strcmp(buf,"exit")==0){
printf("退出成功!\n");
break;
}
int c1=send(sock,buf,strlen(buf),0);
}

close(sock); // 关闭监听套接字

printf("按回车键继续...");
getchar(); // 等待任意按键
}

实验体会

这次实验内容很多,我花了很长时间才完成。遇到的困难主要有:
1.windows系统下Telnet用不了,并不清楚为什么。折腾了一番之后只能在wsl(一个能在windows下跑的linux子系统)下用telnet。不过后来看到实验要自己写一个telnet,就又写了一个。
2.在写Telnet的过程中也遇到了很多问题,一个是不知道怎么把域名转为ip地址,后来在一篇博客上找到了相关的函数。第二个问题是连接网页的时候总是报 400 错误,找了半天发现是回车符的问题,把所有的\n改为\r\n后就解决了。其他的部分就简单了,我一开始以为要写很久,后来发现只要把实验二的客户端代码改一下就完成了。
3.对MIME格式文件不是很熟悉,看了很久才看明白(可能是上课听讲不认真)。
总的来说这次实验还是很有价值的,一方面锻炼了编程能力,另一方面也学到了很多应用层的相关知识,期待下一个实验的到来。