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 作业的更多相关文章

  1. day26作业

    1.整理TCP三次握手.四次挥手图 2.基于TCP开发一款远程CMD程序 客户端连接服务器后,可以向服务器发送命令 服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端 注意 ...

  2. day26 作业(ATM第二版)

    目录 start.py conf.settings.py core.src.py db.db_handler.py interface.bank_interface.py interface.shop ...

  3. Spark Streaming揭秘 Day26 JobGenerator源码图解

    Spark Streaming揭秘 Day26 JobGenerator源码图解 今天主要解析一下JobGenerator,它相当于一个转换器,和机器学习的pipeline比较类似,因为最终运行在Sp ...

  4. CRM项目之RBAC权限组件-day26

    写在前面 上课第26天,打卡: 世间安得双全法 不负如来不负卿 s17day26 CRM项目 项目概要:XX公司CRM - 权限管理,公共组件,app ***** - 熟悉增删改查,Low *** - ...

  5. python 全栈开发,Day29(昨日作业讲解,模块搜索路径,编译python文件,包以及包的import和from,软件开发规范)

    一.昨日作业讲解 先来回顾一下昨日的内容 1.os模块 和操作系统交互 工作目录 文件夹 文件 操作系统命令 路径相关的 2.模块 最本质的区别 import会创建一个专属于模块的名字, 所有导入模块 ...

  6. python 作业

    Linux day01 计算机硬件知识整理 作业要求:整理博客,内容如下 编程语言的作用及与操作系统和硬件的关系 应用程序->操作系统->硬件 cpu->内存->磁盘 cpu与 ...

  7. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  8. SQLServer2005创建定时作业任务

    SQLServer定时作业任务:即数据库自动按照定时执行的作业任务,具有周期性不需要人工干预的特点 创建步骤:(使用最高权限的账户登录--sa) 一.启动SQL Server代理(SQL Server ...

  9. 使用T-SQL找出执行时间过长的作业

        有些时候,有些作业遇到问题执行时间过长,因此我写了一个脚本可以根据历史记录,找出执行时间过长的作业,在监控中就可以及时发现这些作业并尽早解决,代码如下:   SELECT sj.name , ...

随机推荐

  1. thinkphp ajax返回

    ThinkPHP可以很好的支持AJAX请求,系统的\Think\Controller类提供了ajaxReturn方法用于AJAX调用后返回数据给客户端.并且支持JSON.JSONP.XML和EVAL四 ...

  2. day 56 Django基础五之django模型层(二)多表操作

    Django基础五之django模型层(二)多表操作   本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 ORM ...

  3. docker企业级镜像仓库harbor

    第一步:安装docker和docker-compose 第二步:下载harbor-offine-installer-v1.5.1.tgz 第三步:上传到/opt,并解压 第四步:修改harbor.cf ...

  4. Mysql优化系列之查询优化干货1

    从这一篇开始,准备总结一些直接受用的sql语句优化,写sql是第二要紧的,第一要紧的,是会分析怎么查最快, 因为当你写过很多sql后,查询出结果已经不是目标,快,才是目标.另外,通过测试和比较的结果才 ...

  5. nginx i.com.conf

    server { listen 9090; server_name i.com; root /Users/chong/Documents/www; # Load configuration files ...

  6. 利用HttpWebRequest模拟提交图片

    利用HttpWebRequest模拟提交图片 最近在做排量post工具, 以前做的都是提交文字 这次需要post图片过去,弄了半天终于弄好了: /// <summary> /// Post ...

  7. ie中onclick问题

    代码:<button > <span onclick="xxx();">确定</span></button> 在chrome和fir ...

  8. thml粘连布局

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  9. js实现把多个数据分成3个一组

    主要代码: var stuCount = res.data; if (stuCount.length>0){ var objList = new Object(); var arr = new ...

  10. mysql 存中文失败问题

    在向数据库存中文时报错: 将中文字段的字符集改为utf8即可: 成功截图: