├── 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 | ![IMG](../IMG/printer.png) 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. ![IMG](../IMG/1.png) 偷个懒用别人的表格(数据都是一样的,逃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. ![IMG](../IMG/2.png) 21 | --- 22 | 13. ![IMG](../IMG/3.png) -------------------------------------------------------------------------------- /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. ![IMG](../IMG/3.png) 17 | 9. 应该没有中继代理,dhcp的中继代理是用来跨网段分配ip的,通过dhcp服务器转发给另一个dhcp服务器,让它来处理,再把结果再转发回来(稍微了解下就行) 18 | 10. 路由器提供中继代理,子网掩码是区分网段 ![IMG](../IMG/4.png) 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 ![IMG](../IMG/5.png) 22 | 14. 获取MAC地址放入缓存表 ![IMG](../IMG/6.png) -------------------------------------------------------------------------------- /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 ![IMG](../IMG/1.png) 19 | 12. DF是0, MF是0, Offset是1480,最后一片(MF为0) ![IMG](../IMG/2.png) 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地址), 是网关路由器的地址 ![IMG](../IMG/1.png) 13 | 6. 00:d0:59:a9:3d:68, 是我的电脑的MAC地址 14 | 7. 0x0800, IPv4 15 | 8. 68Bytes 16 | --- 17 | 9. 有广播地址,组播地址,路由地址(都是IP+MAC),4个接口(一个无线网卡,一个有线网卡,vpn和虚拟机不知道什么原理也有接口) ![IMG](../IMG/2.png) 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. ![IMG](../IMG/1.png) 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. ![IMG](../IMG/2.png) 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.
![IMG](../IMG/1.png)
6 | 2.
![IMG](../IMG/2.png)
7 | 3. 失败了不知道为啥,理论上没问题啊。。正常nslookup -type=MX yahoo.com没问题 8 | ![IMG](../IMG/3.png) 9 | --- 10 | 4. 通过UDP 11 | 5. 都是53 12 | 6. 是一样的 13 | ![IMG](../IMG/4.png) 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 | ![IMG](../IMG/5.png) 25 | --- 26 | 16. 192.168.43.1(没指定dns服务器当然自然用本地dns服务器咯),是 27 | 17. NS,不包含 28 | 18. 29 | ![IMG](../IMG/7.png) 30 | 不包含 31 | 19. 32 | ![IMG](../IMG/8.png) 33 | --- 34 | 20. 首先发向本地DNS服务器发,请求bitsy.mit.edu的dns服务器地址;然后发向bitsy.mit.edu这个dns服务器进行之后的查询(不过lab给的实例没体现,我的体现了这点,不过后面查那个韩国网站超时) 35 | ![IMG](../IMG/11.png) 36 | 21. 类型是A,不包含 37 | 22. 返回了最终要查的主机的IP地址 38 | ![IMG](../IMG/10.png) 39 | 23. 40 | ![IMG](../IMG/9.png) 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'+'

hello

'+'\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

hello

\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 | --------------------------------------------------------------------------------