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. js 忘记密码发送短信记录cookie

    <div class="forgetPwdBox" style="display:none"> <div class="forTit ...

  2. (转)自定义ClassLoader ----可以加载第三方jar包

    package com.classloader.util; import java.io.IOException; import java.net.MalformedURLException; imp ...

  3. Hadoop 与 Spark 对比

    Hadoop进行海量数据分析,MR频繁落地,IO操作,计算时间就拉长.由于这种设计影响,计算过程中不能进行迭代计算.造成网络节点数据传输. Spark从理念上就开始改变.应用scala特点解决上面的核 ...

  4. os.path.dirname(__file__)使用、Python os.path.abspath(__file__)使用

    python中的os.path.dirname(__file__)的使用 - CSDN博客https://blog.csdn.net/u011760056/article/details/469698 ...

  5. 第十二篇:随手记一下javaBean的setter,getter方法的命名问题

    今天测试新写的一个系统表的完整Ibatis配置和调用,因为经验少,到处撞墙...其他的坑爹问题就不提了 测试sqlMapClient.queryForList("...",para ...

  6. demjson处理json数据

    因为json数据不规范出现了以下问题: json.decoder.JSONDecodeError: Expecting property name enclosed in double quo 网上查 ...

  7. springcloud Eureka Finchley.RELEASE 版本

    创建一个父项目cloud-demo pom.xml <?xml version="1.0" encoding="UTF-8"?> <proje ...

  8. JS流程控制语句 重复重复(for循环)语句结构: for(初始化变量;循环条件;循环迭代) { 循环语句 }

    重复重复(for循环) 很多事情不只是做一次,要重复做.如打印10份试卷,每次打印一份,重复这个动作,直到打印完成.这些事情,我们使用循环语句来完成,循环语句,就是重复执行一段代码. for语句结构: ...

  9. c# 中反射里的invoke方法的参数

    一个最简单的C#反射实例,首先编写类库如下: namespace ReflectionTest { public class WriteTest { //带参数的公共方法 public void Wr ...

  10. 《你不知道的JavaScript》上卷——第1章

    知识点总结 1.什么是作用域? 作用域是根据名称查找变量的一套规则. 2.通常将JavaScript归类为“动态”或“解释执行”语言,但事实上它是一门编译语言. 3.编译 在传统编译语言的流程中,程序 ...