day26 作业
TCP三次握手、四次挥手图

三次握手
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN(c)。此时客户端处于 SYN_Send 状态。
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。
第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 establised 状态。
服务器收到 ACK 报文之后,也处于 establised 状态,此时,双方已建立起了链接。

四次挥手
刚开始双方都处于 establised 状态,假如是客户端先发起关闭请求,则:
- 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
- 第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
- 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
- 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态。服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

简明理解三次握手
第一次握手:Client什么都不能确认;Server确认了对方发送正常
第二次握手:Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自 己接收正常,对方发送正常
第三次握手:Client确认了:自己发送、接收正常,对方发送、接收正常;Server确认了:自己发送、接收正常,对方发送接收正常


基于TCP开发一款远程CMD程序
客户端连接服务器后,可以向服务器发送命令
服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端
注意: 执行系统指令使用subprocess模块完成.
利用 subprocess模块 实现
- 创建popen类的实例化对象
obj = Subprocess.Popen("pwd",shell=True,stdout=subprocess.PIPE) - shell 开启shell
- stdout 重定向结果输出管道
* PIPE 将结果转移到当前主进程 - stdout.read() 获取命令执行的结果,指定结果后会将执行结果封装到指定的对象中,然后通过对象,read()获取执行命令的结果,如果不定义stdout会将结果进行标准输出
# 例子
[root@192.168.32.130 /python]$ cat python-subprocess.py
#coding=utf-8
import subprocess
popen = subprocess.Popen("pwd",shell=True,stdout=subprocess.PIPE)
print(popen.stdout.read().strip())
[root@192.168.32.130 /python]$
[root@192.168.32.130 /python]$ python3 python-subprocess.py
b'/python'
[root@192.168.32.130 /python]$
# 服务端编写
# coding=utf-8
import socket
import subprocess
sock = socket.socket()
# 重用ip和端口
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('192.168.32.130', 8888))
sock.listen(5)
while True:
print("等待客户端连接...")
conn, addr = sock.accept()
print(f"{addr}成功连接!")
while True:
cmd = conn.recv(1024)
if cmd == "q":
print("客户端退出连接!")
break
print(f"命令是 {cmd.decode('utf-8')}")
# 利用subprocess模块进行系统调用
data = subprocess.Popen(cmd.decode(),shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = data.stdout.read()
stderr = data.stderr.read()
# 打包执行结果
res = stdout + stderr
# 发送执行结果
conn.send(res)
conn.close()
# 客户端编写
# coding=utf-8
import socket
sock = socket.socket()
sock.connect(('192.168.32.130', 8888))
while True:
cmd = input("请输入你要执行的命令").strip()
if not cmd:
print("不能为空!")
continue
elif cmd == 'exit':
break
sock.send(cmd.encode('utf-8'))
data = sock.recv(1024)
print(data.decode('utf-8'))
sock.close()
终端打印结果

利用 os模块 实现
# 服务端
# coding=utf-8
import os
import socket
sock = socket.socket()
# 重置ip和端口
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
address = ("192.168.32.130",8888)
sock.bind(address)
sock.listen(5)
while True:
print("等待客户端连接...")
conn,addr = sock.accept()
print(f"来自客户端地址{addr}连接成功!")
while True:
cmd = conn.recv(1024)
if not cmd:
print("客户端断开连接...")
break
print(f"客户端执行了命令:{cmd}")
# 利用os模块的popen方法执行命令
data = os.popen(cmd.decode("utf-8")).read()
conn.send(data.encode("utf-8"))
conn.close()
# coding=utf-8
import socket
sock = socket.socket()
address = ("192.168.32.130",8888)
sock.connect(address)
while True:
cmd = input("请输入你要执行的命令>>>").strip()
if not cmd:
continue
if cmd == "exit":
break
sock.send(cmd.encode("utf-8"))
data = sock.recv(1024)
print(data.decode("utf-8"))
sock.close()
day26 作业的更多相关文章
- day26作业
1.整理TCP三次握手.四次挥手图 2.基于TCP开发一款远程CMD程序 客户端连接服务器后,可以向服务器发送命令 服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端 注意 ...
- day26 作业(ATM第二版)
目录 start.py conf.settings.py core.src.py db.db_handler.py interface.bank_interface.py interface.shop ...
- Spark Streaming揭秘 Day26 JobGenerator源码图解
Spark Streaming揭秘 Day26 JobGenerator源码图解 今天主要解析一下JobGenerator,它相当于一个转换器,和机器学习的pipeline比较类似,因为最终运行在Sp ...
- CRM项目之RBAC权限组件-day26
写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...
- python 全栈开发,Day29(昨日作业讲解,模块搜索路径,编译python文件,包以及包的import和from,软件开发规范)
一.昨日作业讲解 先来回顾一下昨日的内容 1.os模块 和操作系统交互 工作目录 文件夹 文件 操作系统命令 路径相关的 2.模块 最本质的区别 import会创建一个专属于模块的名字, 所有导入模块 ...
- python 作业
Linux day01 计算机硬件知识整理 作业要求:整理博客,内容如下 编程语言的作用及与操作系统和硬件的关系 应用程序->操作系统->硬件 cpu->内存->磁盘 cpu与 ...
- python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)
类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...
- SQLServer2005创建定时作业任务
SQLServer定时作业任务:即数据库自动按照定时执行的作业任务,具有周期性不需要人工干预的特点 创建步骤:(使用最高权限的账户登录--sa) 一.启动SQL Server代理(SQL Server ...
- 使用T-SQL找出执行时间过长的作业
有些时候,有些作业遇到问题执行时间过长,因此我写了一个脚本可以根据历史记录,找出执行时间过长的作业,在监控中就可以及时发现这些作业并尽早解决,代码如下: SELECT sj.name , ...
随机推荐
- MySQL 其他基础知识
-- 查询存储引擎show engines;-- 显示可用存储引擎show variables like 'have%'; -- concat多个字段联合select tname ,cname ,co ...
- 0704 Process继承实现多进程、Pool进程池,进程间通过队列通信,Pool实现多进程实现复制文件
通过继承的方式,实现Process多进程 from multiprocessing import Process import time class MyNewProcess(Process): de ...
- day25 模块,sys, logging, json, pickle
Python之路,Day13 = Python基础13 sys模块 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sy ...
- 如何区分无线AP跟无线路由器
无线AP是一个无线网络的接入点,俗称“热点”.主要有路由交换接入一体设备和纯接入点设备,一体设备执行接入和路由工作,纯接入设备只负责无线客户端的接入,纯接入设备通常作为无线网络扩展使用,与其他AP或者 ...
- JSON对象和字符串之间的相互转换 – JSON.parse() 和 JSON.stringify()
所有现代浏览器都支持 JSON 对象,有两个非常有用的方法来处理 JSON 格式的内容: JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象 ...
- 新金融ABS如何做?听听这几十家券商、互金高管的经验之谈
新金融ABS如何做?听听这几十家券商.互金高管的经验之谈 2016-11-24 零壹财经 ID:36104743 时间:2016年11月初 地点:北京东城区南湾子3号院(场地提供方:无讼.天同律师事务 ...
- PPM 信号解析
PWM信号 PWM信号用于控制单个电调或者单个舵机脉冲宽度调制信号. 像华科尔DEVO 10遥控接收器(RX1002)就输出10路PWM,参看下图. 舵机(电调)上用到PWM信号种类很多,我们这里对常 ...
- UVA-307-Sticks-dfs+剪枝
George took sticks of the same length and cut them randomly until all parts became at most 50 units ...
- 根据Cron表达式,通过Spring自带的CronSequenceGenerator类获取下次执行时间
Cron表达式通常用于执行一些定时任务,在本篇文章中,暂时不会记录如何根据Cron表达式来执行一些定时任务.本章主要的目的是根据Cron表达式,通过Spring自带的CronSequenceGener ...
- Lost's revenge HDU - 3341 AC自动机+DP(需要学会如何优雅的压缩状态)
题意: 给你n个子串和一个母串,让你重排母串最多能得到多少个子串出现在重排后的母串中. 首先第一步肯定是获取母串中每个字母出现的次数,只有A T C G四种. 这个很容易想到一个dp状态dp[i][A ...