├── CH2
├── Programing
│ ├── WebServer
│ │ ├── index.html
│ │ ├── WebClient.py
│ │ ├── WebServer.py
│ │ └── WebServer2.py
│ ├── SMTP
│ │ ├── 02.jpg
│ │ ├── SMTPclient.py
│ │ ├── SMTPclientSSL.py
│ │ └── SMTPclientPicuter.py
│ ├── WebProxy
│ │ ├── gaia.cs.umass.edu_wireshark-labs_INTRO-wireshark-file1.html
│ │ └── WebProxy.py
│ └── UDPping
│ │ ├── HBclient.py
│ │ ├── UDPPingServer.py
│ │ ├── HBserver.py
│ │ └── UDPPingClient.py
├── IMG
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ ├── 9.png
│ ├── 10.png
│ └── 11.png
├── BookExample
│ ├── UDPserver.py
│ ├── UDPclient.py
│ ├── TCPclient.py
│ └── TCPserver.py
└── Wireshark
│ ├── WiresharkLab2.md
│ └── WiresharkLab3.md
├── CH3
├── IMG
│ ├── 1.png
│ ├── 2.png
│ └── 3.png
└── Wireshark
│ ├── WiresharkLab5.md
│ └── WiresharkLab4.md
├── CH4
├── IMG
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ └── 6.png
├── Wireshark
│ ├── WiresharkLab7.md
│ ├── WiresharkLab8.md
│ ├── WiresharkLab9.md
│ └── WiresharkLab6.md
└── Program
│ └── ICMPping.py
├── CH5
├── IMG
│ ├── 1.png
│ └── 2.png
└── Wireshark
│ └── Wiresharklab10.md
├── CH8
├── IMG
│ ├── 1.png
│ └── 2.png
└── Wireshark
│ └── Wiresharklab12.md
├── CH1
├── IMG
│ └── printer.png
└── Wireshark
│ └── WiresharkLab1.md
├── .vscode
└── launch.json
└── README.md
/CH2/Programing/WebServer/index.html:
--------------------------------------------------------------------------------
1 | This is what you looking for.
--------------------------------------------------------------------------------
/CH2/IMG/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/1.png
--------------------------------------------------------------------------------
/CH2/IMG/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/2.png
--------------------------------------------------------------------------------
/CH2/IMG/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/3.png
--------------------------------------------------------------------------------
/CH2/IMG/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/4.png
--------------------------------------------------------------------------------
/CH2/IMG/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/5.png
--------------------------------------------------------------------------------
/CH2/IMG/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/6.png
--------------------------------------------------------------------------------
/CH2/IMG/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/7.png
--------------------------------------------------------------------------------
/CH2/IMG/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/8.png
--------------------------------------------------------------------------------
/CH2/IMG/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/9.png
--------------------------------------------------------------------------------
/CH3/IMG/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH3/IMG/1.png
--------------------------------------------------------------------------------
/CH3/IMG/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH3/IMG/2.png
--------------------------------------------------------------------------------
/CH3/IMG/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH3/IMG/3.png
--------------------------------------------------------------------------------
/CH4/IMG/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/1.png
--------------------------------------------------------------------------------
/CH4/IMG/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/2.png
--------------------------------------------------------------------------------
/CH4/IMG/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/3.png
--------------------------------------------------------------------------------
/CH4/IMG/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/4.png
--------------------------------------------------------------------------------
/CH4/IMG/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/5.png
--------------------------------------------------------------------------------
/CH4/IMG/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH4/IMG/6.png
--------------------------------------------------------------------------------
/CH5/IMG/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH5/IMG/1.png
--------------------------------------------------------------------------------
/CH5/IMG/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH5/IMG/2.png
--------------------------------------------------------------------------------
/CH8/IMG/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH8/IMG/1.png
--------------------------------------------------------------------------------
/CH8/IMG/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH8/IMG/2.png
--------------------------------------------------------------------------------
/CH2/IMG/10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/10.png
--------------------------------------------------------------------------------
/CH2/IMG/11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/IMG/11.png
--------------------------------------------------------------------------------
/CH1/IMG/printer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH1/IMG/printer.png
--------------------------------------------------------------------------------
/CH2/Programing/SMTP/02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunhuiquan/A-Top-Down-Approach/HEAD/CH2/Programing/SMTP/02.jpg
--------------------------------------------------------------------------------
/CH1/Wireshark/WiresharkLab1.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 实验内容非常简单,跟着指导照做就行。
3 | ***
4 | 答案:
5 | 1. TCP,UDP,DNS等等
6 | 2. 0.55s
7 | 3. 我26.26.26.1 服务器128.119.245.12
8 | 4. pdf截图
9 | 
10 |
--------------------------------------------------------------------------------
/CH2/Programing/WebProxy/gaia.cs.umass.edu_wireshark-labs_INTRO-wireshark-file1.html:
--------------------------------------------------------------------------------
1 | HTTP/1.1 304 Not Modified
2 | Date: Fri, 26 Feb 2021 02:18:09 GMT
3 | Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.14 mod_perl/2.0.11 Perl/v5.16.3
4 | ETag: "51-5bc23afbdae95"
5 |
6 |
--------------------------------------------------------------------------------
/CH3/Wireshark/WiresharkLab5.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 这个lab好简单。。
3 |
4 | ---
5 | Answer:
6 | 1. 源端口,目的端口,校验和,UDP报文长度
7 | 2. 8B
8 | 3. header和payload的长度
9 | 4. 2^16 - 8 Bytes(UDP上的length是16位)(当然由于MTU这只是理论值)
10 | 5. 2^16 - 1
11 | 6. 6(TCP)和17(UDP) (看IP的protocol字段就可以了)
12 | 7. 源端口号变目的端口号,目的端口号变源端口号
13 |
--------------------------------------------------------------------------------
/CH2/BookExample/UDPserver.py:
--------------------------------------------------------------------------------
1 | from socket import *
2 |
3 |
4 | def main():
5 | serverPort = 12000
6 | serverSocket = socket(AF_INET, SOCK_DGRAM)
7 | serverSocket.bind(('', serverPort))
8 | print('Ready to receive.')
9 | while True:
10 | message, clientAddress = serverSocket.recvfrom(2048)
11 | modifiedMessage = message.decode().upper()
12 | serverSocket.sendto(modifiedMessage.encode(), clientAddress)
13 |
14 |
15 | if __name__ == '__main__':
16 | main()
17 |
--------------------------------------------------------------------------------
/CH2/BookExample/UDPclient.py:
--------------------------------------------------------------------------------
1 | from socket import *
2 |
3 | def main():
4 | serverName = 'localhost'
5 | serverPort = 12000
6 | clientSocket = socket(AF_INET,SOCK_DGRAM)
7 | message = input('Input lowercase sentence:')
8 | clientSocket.sendto(message.encode(),(serverName,serverPort))
9 | modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
10 | print(modifiedMessage.decode())
11 | clientSocket.close()
12 | input()
13 |
14 |
15 | if __name__ == '__main__':
16 | main()
--------------------------------------------------------------------------------
/CH2/BookExample/TCPclient.py:
--------------------------------------------------------------------------------
1 | from socket import *
2 |
3 |
4 | def main():
5 | serverName = 'localhost'
6 | serverPort = 12000
7 | clientSocket = socket(AF_INET, SOCK_STREAM)
8 | clientSocket.connect((serverName, serverPort))
9 | sentence = input('Input lowercase sentence:')
10 | clientSocket.send(sentence.encode())
11 | modifiedSentence = clientSocket.recv(1024).decode()
12 | print(modifiedSentence)
13 | clientSocket.close()
14 | input()
15 |
16 |
17 | if __name__ == '__main__':
18 | main()
19 |
--------------------------------------------------------------------------------
/CH2/BookExample/TCPserver.py:
--------------------------------------------------------------------------------
1 | from socket import *
2 |
3 |
4 | def main():
5 | serverPort = 12000
6 | serverSocket = socket(AF_INET, SOCK_STREAM)
7 | serverSocket.bind(('', serverPort))
8 | serverSocket.listen(1)
9 | print('Ready to receive!')
10 | while True:
11 | connectSocket, addr = serverSocket.accept()
12 | sentence = connectSocket.recv(1024).decode()
13 | capitailizedSentence = sentence.upper()
14 | connectSocket.send(capitailizedSentence.encode())
15 | connectSocket.close()
16 |
17 |
18 | if __name__ == '__main__':
19 | main()
20 |
--------------------------------------------------------------------------------
/CH2/Programing/UDPping/HBclient.py:
--------------------------------------------------------------------------------
1 | # Task 2
2 | from socket import *
3 | import time
4 |
5 |
6 | def main():
7 | serverName = 'localhost'
8 | serverPort = 12000
9 | clientSocket = socket(AF_INET, SOCK_DGRAM)
10 | times = 0
11 | while True:
12 | times += 1
13 | message = 'HeartBeat ' + str(time.time())
14 | clientSocket.sendto(message.encode(), (serverName, serverPort))
15 | print('Have sent to server %d times.' % (times))
16 | time.sleep(4.9) # Other code will costs time too.
17 | clientSocket.close()
18 |
19 | if __name__ == '__main__':
20 | main()
21 |
--------------------------------------------------------------------------------
/CH4/Wireshark/WiresharkLab7.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 🤮,有些路由器ttl到期禁止发回icmp消息,我还以为咋了。
3 | 2. 妥协一下用给的wireshark文件咯。
4 |
5 | ---
6 | Answers:
7 | 1. 192.168.43.90 and 143.89.12.134
8 | 2. 因为ICMP是一种基于IP的IP控制报文,是一种网络层的协议(一般认为),和它相关的只是主机到主机的传输,根本不涉及运输层的多路复用与分解,因而不需要port
9 | 3. Type:8 Echo(ping) request;Code是0;校验和2B,标识符2B,序列号2B
10 | 4. Type:0 Echo(ping) reply;Code是0;校验和2B,标识符2B,序列号2B
11 | ---
12 | 5. 192.168.1.101, 最终的目标地址是138.96.146.2(就是我们发的IP报文中写的,不一定能到达,比如ttl到0,最后中间的路由器发回icmp报文(如果允许的话))
13 | 6. UDP是17,ICMP才是1
14 | 7. 不同,比如tracert会有type11的ttl为0的ICMP报文
15 | 8. 多了一开始的ICMP请求报文
16 | 9. 最后三个是成功到达了最终IP目标地址(ttl为0时刚好到了,不再跳步所以没问题),是type为8的ping响应ICMP报文
17 | 10. 最后一个路由器应该跨越美国到法国了,所以慢
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Python",
9 | "type": "python",
10 | "request": "launch",
11 | "program": "${file}",
12 | "cwd": "${fileDirname}",
13 | // 解决相对路径问题,原来的VSC默认的相对路径起始在整个根工作区目录,
14 | // 现在改为当前目录
15 | "console": "externalTerminal",
16 | "args": ["8899"]
17 | // "console": "integratedTerminal"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/CH3/Wireshark/WiresharkLab4.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 26.26.26.1是因为开了VPN,其他不影响(关了也是192这样的保留段,但是不开VPN我连不到外网做不了实验。。)
3 | 2. wireshark抓取的http协议包在数据传输过程中显示的是TCP协议,只有建立连接和断开连接那几个包才显示为http,害我纠结了好一阵。
4 | 3. wireshark生成图形的功能好强大。。
5 |
6 | ---
7 | Answer:
8 | 1. 192.168.1.102,Port 1161
9 | 2. 128.119.245.12,Port 80
10 | 3. 26.26.26.1,Port 8026
11 | ---
12 | 4. seq:232129012(absolute seqno:0),三次握手的一二次握手,用于建立TCP连接
13 | 5. seq:883061785(absolute seqno:0),ack:232129013, ack是第一个未接受到的位置(即第一个期望下一次能收到报文位置),二次握手SYN + ACK通知客户端已经收到了来自客户端的SYN
14 | 6. 232129012(absolute seqno:1)
15 | 7.  偷个懒用别人的表格(数据都是一样的,逃XD)
16 | 8. 565,1460,1460,1460,1460,1460
17 | 9. WIN最小是5840,没有到过0,接收窗口大小(ack报文的时候会发送这个window_size)会限制发送窗口大小,说明接受窗口没有限制发送
18 | 10. 没有,因为检查了seqno是一直连续增大的。
19 | 11. 在wireshark的结果中显示不是累计确认的,看了ack的值都是对应客户端的seq变化而一对一变化,没有发现一个ack对应多个seq的情况。
20 | 12. 
21 | ---
22 | 13. 
--------------------------------------------------------------------------------
/CH4/Wireshark/WiresharkLab8.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 由于太过麻烦,直接用了课程的抓包了。。
3 |
4 | ---
5 | Answer:
6 | 1. 通过UDP
7 | 2. 1)0.0.0.0未绑定的dhcp客户通过目的255.255.255.255广播请求;2)dhcp服务器做出响应,里面有提供的ip;3)0.0.0.0广播自己的选择;4)dhcp响应确认。之后新的机器就有IP了。
8 | 3. MAC地址是00:08:74:4f:36:23
9 | 4. option不同
10 | 5. 0x3e5e0ce3,说明哪些是同一个主机的事务,避免给多个新来主机同时提供dhcp服务造成混乱
11 | 6. 0.0.0.0 255.255.255.255
12 | 192.168.1.1 255.255.255.255
13 | 0.0.0.0 255.255.255.255
14 | 192.168.1.1 255.255.255.255
15 | 7. 192.168.1.1
16 | 8. 
17 | 9. 应该没有中继代理,dhcp的中继代理是用来跨网段分配ip的,通过dhcp服务器转发给另一个dhcp服务器,让它来处理,再把结果再转发回来(稍微了解下就行)
18 | 10. 路由器提供中继代理,子网掩码是区分网段 
19 | 11. server响应是Option: (54) DHCP Server Identifier (192.168.1.1);client请求是Option: (50) Requested IP Address (192.168.1.101)
20 | 12. IP Address Lease Time: (86400s) 1 day
21 | 13. client告诉dhcp服务器取消租用ip 
22 | 14. 获取MAC地址放入缓存表 
--------------------------------------------------------------------------------
/CH4/Wireshark/WiresharkLab9.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 照着做没啥难度。
3 |
4 | ---
5 | Answers:
6 | 1. 192.168.1.100
7 | 2. http && ip.addr == 64.233.169.104
8 | 3. 192.168.1.100:4335 and 64.233.169.104:80
9 | 4. 7.158797, 64.233.169.104:80 and 192.168.1.100:4335
10 | 5. 7.075657, 192.168.1.100:4335 and 64.233.169.104:80; 7.108986, 64.233.169.104:80 and 192.168.1.100:4335
11 | 6. 6.069168, 71.192.34.104:4335 and 64.233.169.104:80, 源IP地址不同(源端口号根据是什么类型的NAT可以变也可以不变,比如Basic NAT是无端口号映射的,NAPT是有端口号映射的,支持多个主机共享一个公网IP地址)
12 | 7. http报文没有改变,校验和改了,没改标识,因为ttl每经过一个路由器自己-1,而且源ip地址也被nat修改了,因此需要重新计算校验和,是同一个报文
13 | 8. 6.117570, 64.233.169.104:80 and 71.192.34.104:4335, 校验和、目的IP和ttl不同。
14 | 9. SYN: 6.035475, 71.192.34.104:4335 and 64.233.169.104:80; SYN+ACK: 6.067775, 64.233.169.104:80 and 71.192.34.104:4335
15 | 10. |WAN LAN
16 | |71.192.34.104,4335 192.168.1.100,4335
17 |
18 |
--------------------------------------------------------------------------------
/CH4/Wireshark/WiresharkLab6.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. tracert指令就我的网关路由器还给我发ICMP,其他的路由器都不给我发,都是超时,🤮还是下个软件吧。
3 |
4 | ---
5 | Answers:
6 | 1. 我的IP 192.168.43.90
7 | 2. Protocol: 1(ICMP)
8 | 3. header20B, 有效载荷36B, 用IP的total length减去header length
9 | 4. DF为0,说明可以分片(但不一定分片了);MF为0,说明可能是未分片或者最后一片;检查Fragment Offset为0,说明是第一片不可能是最后一片,因该IP报文此未分片
10 | ---
11 | 5. Checksum, ttl, Identification(16位标识,不断+1来标识)
12 | 6. 保持不变:Sources, Destination, Protocol, Header Length, Version;必须保持不变:Sources, destination, Protocol, Version;必须更改的是:Header checksum, TTL, Identification
13 | 7. Identification随不断发送而增加(+1)
14 | 8. 0x2f19,50
15 | 9. Identification变了,因为IP标识是唯一的;ttl都是50
16 | ---
17 | 10. 分成两段,第一个分组是1480B加上20B的IP header正好是MTU
18 | 11. DF是0, MF是1, Offset是0 
19 | 12. DF是0, MF是0, Offset是1480,最后一片(MF为0) 
20 | 13. Total Length, Flags, Header checksum
21 | ---
22 | 14. 3个
23 | 15. Total Length, Flags, Header checksum
24 |
--------------------------------------------------------------------------------
/CH5/Wireshark/Wiresharklab10.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 了解了下ARP的作用,有网络层的都有路由转发表,通过路由表得到要往哪个IP去,同网段的(同一个以太网(局域网))通过ARP获取目标IP的MAC地址,再通过ARP表转发帧,不同网段的先去网关(通过路由去),目的IP是网关,这一步也是通过ARP获取MAC地址,再通过ARP表转发帧。
3 | 2. 路由器之间转发,路由得到IP后,都是通过ARP获得MAC地址,再ARP表转发的。
4 |
5 | ---
6 | Answers:
7 | 1. 00:d0:59:a9:3d:68
8 | 2. 00:06:25:da:af:73, 不是最终目的主机gaia的MAC地址, 是网关路由器的MAC地址
9 | 3. 0x0800, IPv4
10 | 4. 55Bytes
11 | ---
12 | 5. 00:06:25:da:af:73(以太网地址是MAC地址), 是网关路由器的地址 
13 | 6. 00:d0:59:a9:3d:68, 是我的电脑的MAC地址
14 | 7. 0x0800, IPv4
15 | 8. 68Bytes
16 | ---
17 | 9. 有广播地址,组播地址,路由地址(都是IP+MAC),4个接口(一个无线网卡,一个有线网卡,vpn和虚拟机不知道什么原理也有接口) 
18 | 10. 00:d0:59:a9:3d:68 and ff:ff:ff:ff:ff:ff
19 | 11. 0x0800, IPv4
20 | 12. a) 20Bytes
21 | b) 1
22 | c) 包含
23 | d) 操作码可以看出(广播的方式也可以)
24 | 13. a) 20Bytes
25 | b) 2
26 | c) 操作码可以看出(目的地址是请求的源地址也可以)
27 | 14. from 00:06:25:da:af:73 to 00:d0:59:a9:3d:68
28 | 15. arp回复是单播的这台电脑当然收不到
--------------------------------------------------------------------------------
/CH2/Programing/WebServer/WebClient.py:
--------------------------------------------------------------------------------
1 | # Task 3 2021/2/23 14:14 SunHuiquan
2 |
3 | from socket import *
4 |
5 |
6 | def main():
7 | serverName = 'localhost'
8 | serverPort = 6789
9 | clientSocket = socket(AF_INET, SOCK_STREAM)
10 | clientSocket.connect((serverName, serverPort))
11 | rqeuestFile = input('What are you looking for?\n')
12 | requestHeader = 'Get /' + rqeuestFile + ' HTTP/1.1\r\n'
13 | clientSocket.send(requestHeader.encode())
14 | message = clientSocket.recv(1024).decode()
15 | print(message)
16 | if int(message.split()[1]) == 200:
17 | length = int(message.split()[4])
18 | body = ''
19 | for i in range(length):
20 | body += clientSocket.recv(1024).decode()
21 | print(body)
22 | else:
23 | print('Can\'t find the file.')
24 | clientSocket.close()
25 | input()
26 |
27 |
28 | if __name__ == '__main__':
29 | main()
30 |
--------------------------------------------------------------------------------
/CH2/Wireshark/WiresharkLab2.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 吐槽一下我的wireshark一开始经常出现TCP Previous segment not captured的问题,就是wireshark没能捕获到全部tcp段,多试几次就好了。另外看到1460这个TCP segment的length的时候感到真的有一种整洁的美的感觉。。。
3 | ---
4 | Answer:
5 | 1. 均使用HTTP/1.1
6 | 2. zh-CN,zh
7 | 3. my 26.26.26.1, server's 128.119.245.12
8 | 4. 200 OK
9 | 5. Wed, 31 Mar 2021 05:59:01 GMT
10 | 6. 540B
11 | 7. 都有
12 | ---
13 | 8. 没有
14 | 9. 返回了,看响应体有html的内容
15 | 10. 看到了 If-Modified-Since: Wed, 31 Mar 2021 05:59:01 GMT\r\n, 一个时间用于判断服务器是否更新,如果没有更新就使用cache内容
16 | 11. HTTP/1.1 304 Not Modified\r\n
17 | ---
18 | 12. 1个GET,4个TCP分组都有
19 | 13. 第一个
20 | 14. 200 OK
21 | 15. 四个
22 | ---
23 | 16. 3个,178.79.137.164和128.119.245.12
24 | 17. 并行,浏览器支持同时开始多个tcp连接来提高并行性(因为HTTP/1.1所以1个TCP1个HTTP请求,而不是单个TCP但HTTP/2.0同时多个请求并发),另外HTTP1.1的keep-alive与并不并行无关,指的是复用,比如并发多个http请求,每个请求都是keep-alive这样的。
25 | ---
26 | 18. 401 Unauthorized
27 | 19. Authorization: Basic d2lyZXNoYXJrLXN0dWRlbnRzOm5ldHdvcms=(wireshark-students:network的Base64编码(不是加密))
28 |
--------------------------------------------------------------------------------
/CH2/Programing/UDPping/UDPPingServer.py:
--------------------------------------------------------------------------------
1 | # Task 1
2 | # UDPPingerServer.py
3 | # We will need the following module to generate randomized lost packets import random
4 | from socket import *
5 | import random
6 |
7 | # Create a UDP socket
8 | # Notice the use of SOCK_DGRAM for UDP packets
9 | serverSocket = socket(AF_INET, SOCK_DGRAM)
10 | # Assign IP address and port number to socket
11 | serverSocket.bind(('', 12000))
12 |
13 | while True:
14 | # Generate random number in the range of 0 to 10
15 | rand = random.randint(0, 10)
16 | # Receive the client packet along with the address it is coming from
17 | message, address = serverSocket.recvfrom(1024)
18 | # Capitalize the message from the client
19 | message = message.upper()
20 | # If rand is less is than 4, we consider the packet lost and do not respond
21 | if rand < 4:
22 | continue
23 | # Otherwise, the server responds
24 | serverSocket.sendto(message, address)
25 |
--------------------------------------------------------------------------------
/CH8/Wireshark/Wiresharklab12.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 可能wireshark版本问题,有些不对劲,不过凑合了解下就行了
3 | 2. 后半部分抄的作业,看了看解析,因为书上只是浅略讲了讲,对我来说也是不重要,如果以后用到了再学吧。
4 |
5 | ---
6 | Answers:
7 | 1. 前面是三次握手的报文,正好3个,估计这个属于他说的前8个帧吧
8 | 客户到服务器 1 Client Hello
9 | 服务器到客户 1 Server Hello
10 | 服务器到客户 2 Certificate, Server Hello Done
11 | 客户到服务器 3 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
12 | 服务器到客户 3 Change Cipher Spec, Encrypted Handshake Message
13 | 2. Version 2B
14 | Length 2B
15 | Content Type 1B
16 | 3. 
17 | 4. 看不到这个值,不过看到这个属性名了
18 | 5. 非对称:RSA
19 | 对称:RC4,DES,RC2
20 | 哈希:MD5,SHA,CBC
21 | 6. 是,MD5
22 | 7. 0000000042dbed248b8831d04cc98c26e5badc4e267c391944f0f070ece57745, 防止重放攻击,提高安全性
23 | 8. 包含,如果SSL连接断开,再次连接时,可以使用该属性重新建立连接,在双方都有缓存的情况下可以省略握手的步骤。
24 | 9. 证书在单独的记录中,因为太长,不适合单独的以太网帧传输
25 | 10. 
26 | 11. 指示后面发送的消息都是加密过的。1字节
27 | 12. Encrypted Handshake Message
28 | 13. 发送了,没有不同
29 | 14. 使用上面协商的加密方法进行加密。应用中没有区分加密的应用程序数据和消息认证码MAC,因此我看不出来。
30 | 15. 第二次连接时,没有发送Client Key Exchange,可能是Seeeion ID的效果。
31 |
--------------------------------------------------------------------------------
/CH2/Wireshark/WiresharkLab3.md:
--------------------------------------------------------------------------------
1 | ps:
2 | 1. 前面要连外网所以我的IP跑到美国那里去了,关了vpn发现要捕获的网络都改变了,无语,给我整蒙了好一会,学到了ipconfig(尤其是选项flushdns清除刷新dns缓存,displaydns列出dns,all全部)和nslookup两个指令
3 | 2. 有些地方还超时,吐了🤮,韩国网站,开了vpn也是,不过韩国好像也有墙,不知道是中国墙还是韩国墙的问题,还是网站本身的问题。
4 | ---
5 | 1.

6 | 2.

7 | 3. 失败了不知道为啥,理论上没问题啊。。正常nslookup -type=MX yahoo.com没问题
8 | 
9 | ---
10 | 4. 通过UDP
11 | 5. 都是53
12 | 6. 是一样的
13 | 
14 | 7. A(主机地址),不包含
15 | 8. 2,告诉的A类型主机Address的信息
16 | 9. 会有相对应的,因为我们正是通过DNS服务域名转IP来获得要访问的IP地址
17 | 10. 并没有(由于我不知道为啥打不开,用的是提供的文件)
18 | ---
19 | 11. 都是53
20 | 12. 192.168.43.1是(ipconfig可以看出来)
21 | 13. 无answer,tpye是A
22 | 14. 3个,就是返回的一些信息,两个cname别名,一个地址
23 | 15.
24 | 
25 | ---
26 | 16. 192.168.43.1(没指定dns服务器当然自然用本地dns服务器咯),是
27 | 17. NS,不包含
28 | 18.
29 | 
30 | 不包含
31 | 19.
32 | 
33 | ---
34 | 20. 首先发向本地DNS服务器发,请求bitsy.mit.edu的dns服务器地址;然后发向bitsy.mit.edu这个dns服务器进行之后的查询(不过lab给的实例没体现,我的体现了这点,不过后面查那个韩国网站超时)
35 | 
36 | 21. 类型是A,不包含
37 | 22. 返回了最终要查的主机的IP地址
38 | 
39 | 23.
40 | 
41 |
--------------------------------------------------------------------------------
/CH2/Programing/UDPping/HBserver.py:
--------------------------------------------------------------------------------
1 | # Task 2
2 | from socket import *
3 | import time
4 |
5 |
6 | def main():
7 | serverPort = 12000
8 | serverSocket = socket(AF_INET, SOCK_DGRAM)
9 | serverSocket.settimeout(5)
10 | serverSocket.bind(('', serverPort))
11 | print('Ready to receive.')
12 | times = 0
13 | missCon = 0
14 | ready = 0
15 | while True:
16 | times += 1
17 | try:
18 | message, clientAddr = serverSocket.recvfrom(1024)
19 | missCon = 0
20 | if ready == 0:
21 | ready = 1
22 | message = message.decode().split()[1]
23 | sentTime = float(message)
24 | print('Time %d: %.3f.' % (times, float(time.time()) - sentTime))
25 | except Exception as e:
26 | # print(e) Use it for contest is very important.
27 | if ready == 0:
28 | continue
29 | else:
30 | missCon += 1
31 | print('Time %d: miss.' % (times))
32 | if(missCon == 3):
33 | print('App exit.')
34 | break
35 | serverSocket.close()
36 | input()
37 |
38 |
39 | if __name__ == '__main__':
40 | main()
41 |
--------------------------------------------------------------------------------
/CH2/Programing/UDPping/UDPPingClient.py:
--------------------------------------------------------------------------------
1 | # task 1
2 | from socket import *
3 | import time
4 |
5 |
6 | def main():
7 | clientSocket = socket(AF_INET, SOCK_DGRAM)
8 | clientSocket.settimeout(1)
9 | serverName = 'localhost'
10 | serverPort = 12000
11 | miss = 0
12 | shortest = 100
13 | longest = 0
14 | sumRtt = 0
15 | for i in range(10): # from 0, 1, 2, ..., 8, 9
16 | start = time.time()
17 | message = ('Ping %d %f' % (i + 1, start))
18 | try:
19 | clientSocket.sendto(message.encode(), (serverName, serverPort))
20 | receiveMessage, serverAddr = clientSocket.recvfrom(1024)
21 | end = time.time()
22 | rtt = end - start
23 | print('RTT is %d %.3fs' % (i + 1, rtt))
24 | if rtt > longest:
25 | longest = rtt
26 | if rtt < shortest:
27 | shortest = rtt
28 | sumRtt += rtt
29 | except Exception as e:
30 | miss += 1
31 | print('Request %d timed out' % (i + 1))
32 | print('\nshortest: %.3fs, longest: %.3fs, average: %.3fs' %
33 | (shortest, longest, sumRtt / 10))
34 | print('send: %d, receive: %d, miss: %d, missing rate: %d%%' %
35 | (10, 10 - miss, miss, miss * 10))
36 | clientSocket.close()
37 | input()
38 |
39 |
40 | if __name__ == '__main__':
41 | main()
42 |
--------------------------------------------------------------------------------
/CH2/Programing/WebServer/WebServer.py:
--------------------------------------------------------------------------------
1 | # Task 1 2021/2/23 9:44 SunHuiquan
2 |
3 | # import socket module
4 | from socket import *
5 | serverSocket = socket(AF_INET, SOCK_STREAM)
6 |
7 | # Prepare a sever socket
8 | #Fill in start
9 | serverPort = 6789
10 | serverSocket.bind(('', serverPort))
11 | serverSocket.listen(1)
12 | #Fill in end
13 |
14 | while True:
15 | # Establish the connection
16 | print('Ready to serve...')
17 | connectionSocket, addr = serverSocket.accept() # Fill here
18 |
19 | try:
20 | message = connectionSocket.recv(1024).decode() # Fill
21 | filename = message.split()[1]
22 | f = open(filename[1:]) # Default use 'r' mode
23 | outputdata = f.read() # Fill
24 |
25 | # Send one HTTP header line into socket
26 | #Fill in start
27 | header = 'HTTP/1.1 200 OK\nContent-Length: %d\n\n' % (len(outputdata))
28 | connectionSocket.send(header.encode())
29 | #Fill in end
30 |
31 | # Send the content of the requested file to the client
32 | for i in range(0, len(outputdata)):
33 | connectionSocket.send(outputdata[i].encode())
34 | connectionSocket.close()
35 | except IOError as e:
36 | # print(e)
37 | # Send response message for file not found)
38 | header = 'HTTP/1.1 404 Not Found\n\n'
39 | connectionSocket.send(header.encode()) # Fill
40 | # Close client socket
41 | connectionSocket.close() # Fill
42 | serverSocket.close()
43 |
--------------------------------------------------------------------------------
/CH2/Programing/WebServer/WebServer2.py:
--------------------------------------------------------------------------------
1 | # Task 2 2021/2/23 13:34 SunHuiquan
2 |
3 | # import socket module
4 | from socket import *
5 | import threading
6 |
7 |
8 | def webServer(connectionSocket):
9 | try:
10 | message = connectionSocket.recv(1024).decode() # Fill
11 | filename = message.split()[1]
12 | f = open(filename[1:]) # Default use 'r' mode
13 | outputdata = f.read() # Fill
14 |
15 | # Send one HTTP header line into socket
16 | # Fill in start
17 | header = 'HTTP/1.1 200 OK\n\n'
18 | connectionSocket.send(header.encode())
19 | # Fill in end
20 |
21 | # Send the content of the requested file to the client
22 | for i in range(0, len(outputdata)):
23 | connectionSocket.send(outputdata[i].encode())
24 | connectionSocket.close()
25 | print('One server done.')
26 | except IOError:
27 | # Send response message for file not found)
28 | header = 'HTTP/1.1 404 Not Found\n\n'
29 | connectionSocket.send(header.encode()) # Fill
30 | # Close client socket
31 | connectionSocket.close() # Fill
32 |
33 |
34 | def main():
35 | serverSocket = socket(AF_INET, SOCK_STREAM)
36 | # Prepare a sever socket
37 | # Fill in start
38 | serverPort = 6789
39 | serverSocket.bind(('', serverPort))
40 | serverSocket.listen(10)
41 | # Fill in end
42 |
43 | while True:
44 | # Establish the connection
45 | print('Ready to serve...')
46 | connectionSocket, addr = serverSocket.accept() # Fill here
47 | thread = threading.Thread(target=webServer, args=(connectionSocket,))
48 | thread.start()
49 | serverSocket.close()
50 |
51 |
52 | if __name__ == '__main__':
53 | main()
54 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Computer Networking : A Top-Down Approach (7th)
2 |
3 | #### 一点小建议:强烈推荐看完自顶向下的链路层后(物理层没有存在感hh),去刷CS144的lab0-lab4,是实现一个miniTCP的lab,刚学完五层模型就去实现个运输层协议绝对不错,我就这样干了(资源可以在我的CS144lab的README找到),我c++入门+一定的数据结构基础+计网看了自顶向下+一点操作系统基础差不多花了60多个小时左右做完了(我把这个当成c++课设了,肝了8天,心累),强烈推荐。另外CS144视频推荐不看,因为确实CS144在YouTube的是远古视频加上感觉哈工大的计网mooc已经质量还不错了,如果需要可以看看CS144相关实验解答的视频,不过我没看。
4 |
5 | ### 【一】Socket Program:
6 | * [CH2 Web Server](CH2/Programing/WebServer)
这个简单,熟悉下api。
7 | * [CH2 UDPping](CH2/Programing/UDPping)
这个简单,熟悉下api。
8 | * [CH2 SMTP Client](CH2/Programing/SMTP)
网易邮箱自动成垃圾,我错了,我是垃圾,搞了半天心态,推荐用qq。
9 | * [CH2 Web Proxy](CH2/Programing/WebProxy)
因为做过CSAPP的proxy lab所以原理很简单,但是给的python模板一堆坑,各种细节问题,尤其是自动发200 OK完全不考虑304 Not Modified,无语了。另外强调下要用给的网站测试,因为这是特意用的http 80端口,现在常用网站基本都是https 443端口了,哭哭,愣了半天才发觉端口不对。(可选都写在一起了,不过没有找到测试post网站)
10 | * [CH4 ICMP Ping](CH4/Program/ICMPping.py)
吐了,这本书给的是python2代码,我连python都不会。。。照着别人答案改成python3,写完。
11 |
12 | ### 【二】Wireshark Experiment:
13 | * [CH1 Intro](CH1/Wireshark/WiresharkLab1.md)
超简单,完全是wireshark入门教程。
14 | * [CH2 HTTP](CH2/Wireshark/WiresharkLab2.md)
挺有意思的,也不难,不过花的时间也要接近1h。。
15 | * [CH2 DNS](CH2/Wireshark/WiresharkLab3.md)
有意思,另外韩国网站整吐了,🤮,开了vpn还是nslookup超时。开了vpn用wireshark测以太网2,关了测wlan(我的笔记本),才发现我IP跑到美国去了。。不过不影响。学了nslookup和ipconfig确实有用。
16 | * [CH3 TCP](CH3/Wireshark/WiresharkLab4.md)
挺有意思,还帮我复习了下我写的miniTCP,另外wireshark好强大。。。
17 | * [CH3 UDP](CH3/Wireshark/WiresharkLab5.md)
快乐复习。
18 | * [CH4 IP](CH4/Wireshark/WiresharkLab6.md)
快乐复习。
19 | * [CH4 ICMP](CH4/Wireshark/WiresharkLab7.md)
快乐复习。
20 | * [CH4 DHCP](CH4/Wireshark/WiresharkLab8.md)
快乐复习。
21 | * [CH4 NAT](CH4/Wireshark/WiresharkLab9.md)
快乐复习。
22 | * [CH5 ARP](CH5/Wireshark/Wiresharklab10.md)
快乐复习。
23 | * CH6 802.11 因为我是CS的,不是搞通信的,书上简略介绍一下对我已经完全够用,就不浪费时间了。
24 | * [CH8 SSL](CH8/Wireshark/Wiresharklab12.md)
稍微看了看复习。
25 |
26 | 习题解析可以看:https://github.com/moranzcw/Computer-Networking-A-Top-Down-Approach-NOTES/blob/master/Resource/Solutions-7th-Edition.docx
27 | 不过说实话不大建议全做,把重要的那几章好好做就好了,其他的看看了解下,这本书不全是给cs的看的,一大块是通信专业的内容,这些我们只需要了解即可。还是多看看面经重要。
28 |
--------------------------------------------------------------------------------
/CH2/Programing/SMTP/SMTPclient.py:
--------------------------------------------------------------------------------
1 | # Task 1 2021/2/25 2:05 SunHuiquan
2 |
3 | from socket import *
4 |
5 | # emailFrom = 'qq number@qq.com'
6 | # emailTo = 'email to@yeah.net'
7 | # emailBase64 = 'email from base64'
8 | # passwordBase64 = 'password base64'
9 |
10 | msg = "\r\n I love computer networks!"
11 | endmsg = "\r\n.\r\n"
12 | # Choose a mail server (e.g. Google mail server) and call it mailserver
13 | mailserver = 'smtp.qq.com' # Fill 1
14 |
15 | # Create socket called clientSocket and establish a TCP connection with mailserver
16 | # Fill 2
17 | clientSocket = socket(AF_INET, SOCK_STREAM)
18 | clientSocket.connect((mailserver, 25))
19 |
20 | recv = clientSocket.recv(1024).decode()
21 | print(recv)
22 | if recv[:3] != '220':
23 | print('220 reply not received from server.')
24 |
25 | # Send HELO command and print server response.
26 | heloCommand = 'HELO Alice\r\n'
27 | clientSocket.send(heloCommand.encode())
28 | recv1 = clientSocket.recv(1024).decode()
29 | print(recv1)
30 | if recv1[:3] != '250':
31 | print('250 reply not received from server.')
32 |
33 | # Auth login
34 | authMsg = 'auth login\r\n'
35 | clientSocket.send(authMsg.encode())
36 | recv2 = clientSocket.recv(1024).decode()
37 | print(recv2)
38 | if recv2[:3] != '334':
39 | print('334 reply not received from server.')
40 |
41 | clientSocket.send(str(emailBase64 + '\r\n').encode())
42 | recv3 = clientSocket.recv(1024).decode()
43 | print(recv3)
44 | if recv3[3] != '334':
45 | print('334 reply not received from server.')
46 |
47 | clientSocket.send(str(passwordBase64 + '\r\n').encode())
48 | recv4 = clientSocket.recv(1024).decode()
49 | print(recv4)
50 | if recv4[:3] != '235':
51 | print('235 reply not received from server.')
52 |
53 | # Send MAIL FROM command and print server response.
54 | # Fill 3
55 | clientSocket.send(str('MAIL FROM:<' + emailFrom + '>\r\n').encode())
56 | recv5 = clientSocket.recv(1024).decode()
57 | print(recv5)
58 | if recv5[:3] != '250':
59 | print('250 reply not received from server.')
60 |
61 | # Send RCPT TO command and print server response.
62 | # Fill 4
63 | clientSocket.send(str('RCPT TO:<' + emailTo + '>\r\n').encode())
64 | recv6 = clientSocket.recv(1024).decode()
65 | print(recv6)
66 | if recv6[:3] != '250':
67 | print('250 reply not received from server.')
68 |
69 | # Send DATA command and print server response.
70 | # Fill 5
71 | clientSocket.send('Data\r\n'.encode())
72 | recv7 = clientSocket.recv(1024).decode()
73 | print(recv7)
74 | if recv7[:3] != '354':
75 | print('354 reply not received from server.')
76 |
77 | # Send message data.
78 | # Fill 6
79 | msgFormat = 'From:<' + emailFrom + '>\r\n'
80 | msgFormat += 'To:<' + emailTo + '>\r\n'
81 | msgFormat += 'Subject:send from python\r\n'
82 | sendMsg = msgFormat + msg + endmsg
83 | clientSocket.send(sendMsg.encode())
84 | recv8 = clientSocket.recv(1024).decode()
85 | print(recv8)
86 | if recv8[:3] != '250':
87 | print('250 reply not received from server.')
88 |
89 | # Send QUIT command and get server response.
90 | # Fill 8
91 | clientSocket.send('QUIT\r\n'.encode())
92 | recv9 = clientSocket.recv(1024).decode()
93 | print(recv9)
94 | if recv9[:3] != '221':
95 | print('221 reply not received from server.')
96 |
97 | # Close the client socket.
98 | clientSocket.close()
99 |
--------------------------------------------------------------------------------
/CH2/Programing/SMTP/SMTPclientSSL.py:
--------------------------------------------------------------------------------
1 | # Task 2 2021/2/25 2:42 SunHuiquan
2 |
3 | from socket import *
4 | import ssl
5 | # emailFrom = 'qq number@qq.com'
6 | # emailTo = 'email to@yeah.net'
7 | # emailBase64 = 'email from base64'
8 | # passwordBase64 = 'password base64'
9 |
10 | msg = "\r\n I love computer networks!"
11 | endmsg = "\r\n.\r\n"
12 | # Choose a mail server (e.g. Google mail server) and call it mailserver
13 | mailserver = 'smtp.qq.com' # Fill 1
14 | context = ssl.create_default_context()
15 | # Create socket called clientSocket and establish a TCP connection with mailserver
16 | # Fill 2
17 | clientSocket = socket(AF_INET, SOCK_STREAM)
18 | clientSocket.connect((mailserver, 465))
19 | clientSocketSSL = context.wrap_socket(clientSocket,server_hostname=mailserver)
20 |
21 | recv = clientSocketSSL.recv(1024).decode()
22 | print(recv)
23 | if recv[:3] != '220':
24 | print('220 reply not received from server.')
25 |
26 | # Send HELO command and print server response.
27 | heloCommand = 'HELO Alice\r\n'
28 | clientSocketSSL.send(heloCommand.encode())
29 | recv1 = clientSocketSSL.recv(1024).decode()
30 | print(recv1)
31 | if recv1[:3] != '250':
32 | print('250 reply not received from server.')
33 |
34 | # Auth login
35 | authMsg = 'auth login\r\n'
36 | clientSocketSSL.send(authMsg.encode())
37 | recv2 = clientSocketSSL.recv(1024).decode()
38 | print(recv2)
39 | if recv2[:3] != '334':
40 | print('334 reply not received from server.')
41 |
42 | clientSocketSSL.send(str(emailBase64 + '\r\n').encode())
43 | recv3 = clientSocketSSL.recv(1024).decode()
44 | print(recv3)
45 | if recv3[3] != '334':
46 | print('334 reply not received from server.')
47 |
48 | clientSocketSSL.send(str(passwordBase64 + '\r\n').encode())
49 | recv4 = clientSocketSSL.recv(1024).decode()
50 | print(recv4)
51 | if recv4[:3] != '235':
52 | print('235 reply not received from server.')
53 |
54 | # Send MAIL FROM command and print server response.
55 | # Fill 3
56 | clientSocketSSL.send(str('MAIL FROM:<' + emailFrom + '>\r\n').encode())
57 | recv5 = clientSocketSSL.recv(1024).decode()
58 | print(recv5)
59 | if recv5[:3] != '250':
60 | print('250 reply not received from server.')
61 |
62 | # Send RCPT TO command and print server response.
63 | # Fill 4
64 | clientSocketSSL.send(str('RCPT TO:<' + emailTo + '>\r\n').encode())
65 | recv6 = clientSocketSSL.recv(1024).decode()
66 | print(recv6)
67 | if recv6[:3] != '250':
68 | print('250 reply not received from server.')
69 |
70 | # Send DATA command and print server response.
71 | # Fill 5
72 | clientSocketSSL.send('Data\r\n'.encode())
73 | recv7 = clientSocketSSL.recv(1024).decode()
74 | print(recv7)
75 | if recv7[:3] != '354':
76 | print('354 reply not received from server.')
77 |
78 | # Send message data.
79 | # Fill 6
80 | msgFormat = 'From:<' + emailFrom + '>\r\n'
81 | msgFormat += 'To:<' + emailTo + '>\r\n'
82 | msgFormat += 'Subject:send from python\r\n'
83 | sendMsg = msgFormat + msg + endmsg
84 | clientSocketSSL.send(sendMsg.encode())
85 | recv8 = clientSocketSSL.recv(1024).decode()
86 | print(recv8)
87 | if recv8[:3] != '250':
88 | print('250 reply not received from server.')
89 |
90 | # Send QUIT command and get server response.
91 | # Fill 8
92 | clientSocketSSL.send('QUIT\r\n'.encode())
93 | recv9 = clientSocketSSL.recv(1024).decode()
94 | print(recv9)
95 | if recv9[:3] != '221':
96 | print('221 reply not received from server.')
97 |
98 | # Close the client socket.
99 | clientSocketSSL.close()
100 |
--------------------------------------------------------------------------------
/CH2/Programing/WebProxy/WebProxy.py:
--------------------------------------------------------------------------------
1 | # Task 1 & 2 2021/2/26 9:20 SunHuiquan
2 |
3 | # coding:utf-8
4 | from socket import *
5 | import sys
6 |
7 | if len(sys.argv) <= 1:
8 | print('Usage : "python ProxyServer.py server_ip"\n\
9 | [server_ip : It is the IP Address Of Proxy Server')
10 | sys.exit(2)
11 | # Create a server socket, bind it to a port and start listening
12 | tcpSerSock = socket(AF_INET, SOCK_STREAM)
13 | # Fill in start.
14 | serverPort = int(sys.argv[1])
15 | tcpSerSock.bind(('', serverPort))
16 | tcpSerSock.listen(10)
17 | # Fill in end.
18 |
19 | while 1:
20 | # Strat receiving data from the client
21 | print('Ready to serve...')
22 | tcpCliSock, addr = tcpSerSock.accept()
23 | print('Received a connection from:', addr)
24 | message = tcpCliSock.recv(4096).decode() # Fill
25 | print(message)
26 |
27 | # Extract the filename from the given message
28 | filename = message.split()[1].partition("//")[2]
29 | # print(filename)
30 | fileExist = "false"
31 | filetouse = "/" + filename
32 | # print(filetouse)
33 |
34 | try:
35 | # Check wether the file exist in the cache
36 | f = open(filetouse[1:].replace('/', '_'), "r")
37 | outputdata = f.readlines()
38 | fileExist = "true"
39 | # ProxyServer finds a cache hit and generates a response message
40 | if(outputdata[0].split()[1] != '304'):
41 | tcpCliSock.send("HTTP/1.0 200 OK\r\n".encode())
42 | tcpCliSock.send("Content-Type:text/html\r\n".encode())
43 | # Fill in start.
44 | print(outputdata)
45 | for s in outputdata:
46 | tcpCliSock.send(s.encode())
47 | # Fill in end.
48 | print('Read from cache')
49 | # Error handling for file not found in cache
50 | except IOError:
51 | if fileExist == "false":
52 | # Create a socket on the proxyserver
53 | c = socket(AF_INET, SOCK_STREAM) # Fill
54 | resourceServerName = filename.partition("/")[0]
55 | print(resourceServerName)
56 |
57 | try:
58 | # Connect to the socket to port 80
59 | # Fill in start.
60 | c.connect((resourceServerName, 80))
61 | c.sendall(message.encode())
62 | buff = c.recv(4096)
63 | print(buff)
64 | tcpCliSock.sendall(buff)
65 | # Fill in end.
66 |
67 | # Create a new file in the cache for the requested file.
68 | # Also send the response in the buffer to client socket and the corresponding file in the cache
69 | fn = filename.replace('/', '_')
70 | # print(fn)
71 | # 文件名不能有/所以要换成别的字符比如_,记得查找的创建文件的时候调整一下文件名字符串
72 | tmpFile = open("./" + fn, "w")
73 | # Fill in start.
74 | print('------------'+str(len(buff)))
75 | tmpFile.writelines(buff.decode().replace('\r\n', '\n'))
76 | tmpFile.close()
77 | # Fill in end.
78 | except Exception as e:
79 | print(e)
80 | print("Illegal request")
81 | else:
82 | # HTTP response message for file not found
83 | # Fill in start.
84 | # 这里是指在资源服务器上找不到,不是代理服务器找不到
85 | print('404 File Not Found.')
86 | # Fill in end.
87 | # Close the client and the server sockets
88 | tcpCliSock.close()
89 | # Fill in start.
90 | tcpSerSock.close()
91 | # Fill in end.
92 |
--------------------------------------------------------------------------------
/CH4/Program/ICMPping.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import os
3 | import sys
4 | import struct
5 | import time
6 | import select
7 | import binascii
8 |
9 | ICMP_ECHO_REQUEST = 8
10 |
11 |
12 |
13 | def checksum(strCheck):
14 | csum = 0
15 | countTo = (len(strCheck) / 2) * 2
16 | count = 0
17 | while count < countTo:
18 | thisVal = strCheck[count + 1] * 256 + strCheck[count]
19 | csum = csum + thisVal
20 | csum = csum & 0xffffffff
21 | count = count + 2
22 |
23 | if countTo < len(strCheck):
24 | csum = csum + strCheck[len(strCheck) - 1]
25 | csum = csum & 0xffffffff
26 |
27 | csum = (csum >> 16) + (csum & 0xffff)
28 | csum = csum + (csum >> 16)
29 | answer = ~csum
30 | answer = answer & 0xffff
31 | answer = answer >> 8 | (answer << 8 & 0xff00)
32 | return answer
33 |
34 |
35 | def receiveOnePing(mySocket, ID, timeout, destAddr):
36 | timeLeft = timeout
37 |
38 | while 1:
39 | startedSelect = time.time()
40 | whatReady = select.select([mySocket], [], [], timeLeft)
41 | howLongInSelect = (time.time() - startedSelect)
42 | if whatReady[0] == []: # Timeout
43 | return "Request timed out."
44 |
45 | timeReceived = time.time()
46 | recPacket, addr = mySocket.recvfrom(1024)
47 |
48 | header = recPacket[20:28]
49 | header_type, header_code, header_checksum, header_packet_ID, header_sequence = struct.unpack("bbHHh", header)
50 |
51 | timeLeft = timeLeft - howLongInSelect
52 | if(header_type == 0 and header_packet_ID == ID):
53 | return timeLeft
54 | else:
55 | return "Receive error."
56 |
57 | if timeLeft <= 0:
58 | return "Request timed out."
59 |
60 |
61 | def sendOnePing(mySocket, destAddr, ID):
62 | # Header is type (8), code (8), checksum (16), id (16), sequence (16)
63 |
64 | myChecksum = 0
65 | # Make a dummy header with a 0 checksum.
66 | # struct -- Interpret strings as packed binary data
67 | header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
68 | data = struct.pack("d", time.time())
69 | # Calculate the checksum on the data and the dummy header.
70 | myChecksum = checksum(header + data)
71 |
72 | # Get the right checksum, and put in the header
73 | if sys.platform == 'darwin':
74 | myChecksum = socket.htons(myChecksum) & 0xffff
75 | # Convert 16-bit integers from host to network byte order.
76 | else:
77 | myChecksum = socket.htons(myChecksum)
78 |
79 | header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
80 | packet = header + data
81 |
82 | mySocket.sendto(packet, (destAddr, 1)) # AF_INET address must be tuple, not str
83 | # Both LISTS and TUPLES consist of a number of objects
84 | # which can be referenced by their position number within the object
85 |
86 |
87 | def doOnePing(destAddr, timeout):
88 | icmp = socket.getprotobyname("icmp")
89 |
90 | mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
91 |
92 | myID = os.getpid() & 0xFFFF # Return the current process i
93 | sendOnePing(mySocket, destAddr, myID)
94 | delay = receiveOnePing(mySocket, myID, timeout, destAddr)
95 |
96 | mySocket.close()
97 | return delay
98 |
99 |
100 | def ping(host, timeout=1):
101 | # timeout=1 means: If one second goes by without a reply from the server,
102 | # the client assumes that either the client’s ping or the server’s pong is lost
103 | # timeout = 1 表示:如果一秒钟没有收到服务器的答复,则客户端会认为客户端的ping或服务器的pong丢失了
104 | dest = socket.gethostbyname(host)
105 | print("Pinging " + dest + " using Python:")
106 | print("")
107 | # Send ping requests to a server separated by approximately one second
108 | while 1:
109 | delay = doOnePing(dest, timeout)
110 | print(delay)
111 | time.sleep(1) # one second
112 |
113 | ping("www.baidu.com")
--------------------------------------------------------------------------------
/CH2/Programing/SMTP/SMTPclientPicuter.py:
--------------------------------------------------------------------------------
1 | # Task 3 2021/2/25 2:49 SunHuiquan
2 |
3 | from socket import *
4 | import base64
5 |
6 | # emailFrom = 'qq number@qq.com'
7 | # emailTo = 'email to@yeah.net'
8 | # emailBase64 = 'email from base64'
9 | # passwordBase64 = 'password base64'
10 |
11 | # Choose a mail server (e.g. Google mail server) and call it mailserver
12 | mailserver = 'smtp.qq.com' # Fill 1
13 |
14 | # Create socket called clientSocket and establish a TCP connection with mailserver
15 | # Fill 2
16 | clientSocket = socket(AF_INET, SOCK_STREAM)
17 | clientSocket.connect((mailserver, 25))
18 |
19 | recv = clientSocket.recv(1024).decode()
20 | print(recv)
21 | if recv[:3] != '220':
22 | print('220 reply not received from server.')
23 |
24 | # Send HELO command and print server response.
25 | heloCommand = 'HELO Alice\r\n'
26 | clientSocket.send(heloCommand.encode())
27 | recv1 = clientSocket.recv(1024).decode()
28 | print(recv1)
29 | if recv1[:3] != '250':
30 | print('250 reply not received from server.')
31 |
32 | # Auth login
33 | authMsg = 'auth login\r\n'
34 | clientSocket.send(authMsg.encode())
35 | recv2 = clientSocket.recv(1024).decode()
36 | print(recv2)
37 | if recv2[:3] != '334':
38 | print('334 reply not received from server.')
39 |
40 | clientSocket.send(str(emailBase64 + '\r\n').encode())
41 | recv3 = clientSocket.recv(1024).decode()
42 | print(recv3)
43 | if recv3[3] != '334':
44 | print('334 reply not received from server.')
45 |
46 | clientSocket.send(str(passwordBase64 + '\r\n').encode())
47 | recv4 = clientSocket.recv(1024).decode()
48 | print(recv4)
49 | if recv4[:3] != '235':
50 | print('235 reply not received from server.')
51 |
52 | # Send MAIL FROM command and print server response.
53 | # Fill 3
54 | clientSocket.send(str('MAIL FROM:<' + emailFrom + '>\r\n').encode())
55 | recv5 = clientSocket.recv(1024).decode()
56 | print(recv5)
57 | if recv5[:3] != '250':
58 | print('250 reply not received from server.')
59 |
60 | # Send RCPT TO command and print server response.
61 | # Fill 4
62 | clientSocket.send(str('RCPT TO:<' + emailTo + '>\r\n').encode())
63 | recv6 = clientSocket.recv(1024).decode()
64 | print(recv6)
65 | if recv6[:3] != '250':
66 | print('250 reply not received from server.')
67 |
68 | # Send DATA command and print server response.
69 | # Fill 5
70 | clientSocket.send('Data\r\n'.encode())
71 | recv7 = clientSocket.recv(1024).decode()
72 | print(recv7)
73 | if recv7[:3] != '354':
74 | print('354 reply not received from server.')
75 |
76 | # Send message data.
77 | # Fill 6
78 | send_text = 'from:%s\r\nto:%s\nsubject:hello,you!\
79 | \r\nContent-Type:text/plain\r\n' % (emailFrom, emailTo)+'\r\n'+'hello'+'\r\n'
80 | print(send_text)
81 | send_text = send_text.encode()
82 |
83 | send_html = 'from:%s\nto:%s\nsubject:hello,you!\
84 | \r\nContent-Type:text/html\r\n' % (emailFrom, emailTo)+'\r\n'+'
'+'\r\n'
85 | print(send_html)
86 | send_html = send_html.encode()
87 |
88 | with open("02.jpg", "rb") as f:
89 | f = base64.b64encode(f.read())
90 | send_image = ('from:%s\nto:%s\nsubject:hello,you!\
91 | \r\nContent-Type:image/JPEG\r\nContent-transfer-encoding:base64\r\n' % (emailFrom, emailTo)+'\r\n').encode()+f+'\r\n'.encode()
92 |
93 | send_text_with_image = 'from:%s\nto:%s\nsubject:hello,you!\
94 | \r\nContent-Type:multipart/mixed;boundary="simple"\r\n\r\n--simple\r\n' % (emailFrom, emailTo)+'Content-Type:text/html\r\n\r\n
\r\n\r\n'
95 | send_text_with_image = send_text_with_image.encode()+'--simple\r\n'.encode() + \
96 | 'Content-Type:image/JPEG\r\nContent-transfer-encoding:base64\r\n\r\n'.encode()
97 | with open("02.jpg", "rb") as f:
98 | f = base64.b64encode(f.read())
99 | send_text_with_image += f
100 | send_text_with_image += '\r\n--simple\r\n'.encode()
101 |
102 | temp = send_text_with_image
103 | print(temp)
104 | clientSocket.send(temp)
105 |
106 |
107 | temp = '\r\n.\r\n'
108 | print(temp)
109 | clientSocket.send(temp.encode())
110 | recv = clientSocket.recv(1024).decode()
111 | print(recv)
112 |
113 | # Send QUIT command and get server response.
114 | # Fill 8
115 | clientSocket.send('QUIT\r\n'.encode())
116 | recv9 = clientSocket.recv(1024).decode()
117 | print(recv9)
118 | if recv9[:3] != '221':
119 | print('221 reply not received from server.')
120 |
121 | # Close the client socket.
122 | clientSocket.close()
123 |
--------------------------------------------------------------------------------