1. 整理TCP三次握手、四次挥手图
三次握手
- 服务器开机,开始listen监听,
- 客户端开机,发送链接请求,进入SYN-SENT(同步已发送)状态,
- 服务端收到链接请求,同意链接,返回发送确定报文,进入SYN-RCVD同步状态,
- 客户端收到同意链接报文,进入established状态,并向服务端给出确认,
- 服务端收到客户端的确认,同步完成,也进入established状态。建立连接成功!
[]
四次挥手
数据传输完毕
- 客户端发送释放链接请求,进入fin-wait1状态(停止发送数据,但可以接收数据),
- 服务端收到释放链接请求,同意释放,返回发送确定报文,进入close-wait状态,
- 客户端接收到同意释放报文,进入fin-wait2状态,接收服务器发送的最后的数据,并等待服务端发送释放链接请求,
- 服务端将最后的数据发送完,发送释放链接请求,进入last-ack状态,等待客户端确认
- 客户端收到释放链接请求,同意释放,返回发送确认报文,进入time-wait状态,等待服务端接收到报文,
- 服务端接收到确认报文,立刻进入closed状态,释放链接,
- 连接被释放,客户端进入closed状态。
(https://img2018.cnblogs.com/blog/1774906/201910/1774906-20191017212935537-1120845795.png)
2. 基于TCP开发一款远程CMD程序
# 需求: # 客户端连接服务器后,可以向服务器发送命令 # 服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端 # 注意: 执行系统指令使用subprocess模块完成.
# 服务端 # socket 基于tcp实现远程执行命令 from socket import * import subprocess tcp_server = socket() tcp_server.bind( ('127.0.0.1', 9528) ) tcp_server.listen(5) while True: conn, addr = tcp_server.accept() while True: try: cmd = conn.recv(1024) if not cmd: break cmd = cmd.decode('utf-8') print('收到客户端命令', cmd) res = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE ) err = res.stderr.read() if err: cmd_res = err else: cmd_res = res.stdout.read() if not cmd_res: cmd_res = '没有结果'.encode('gbk') conn.send(cmd_res) except Exception: break conn.close() break tcp_server.close()
# 客户端 from socket import * tcp_client = socket() tcp_client.connect( ('127.0.0.1', 9528) ) while True: cmd = input('请输入命令').strip() if not cmd: continue if cmd == 'quit': break cmd = cmd.encode('utf-8') tcp_client.send(cmd) cmd_res = tcp_client.recv(1023) # 这里会有粘包现象产生 cmd_res = cmd_res.decode('gbk') print('命令执行的结果是',cmd_res) # windows系统默认编码为gbk