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会将结果进行标准输出
# 例子

[[email protected] /python]$ cat python-subprocess.py
#coding=utf-8
import subprocess
popen = subprocess.Popen("pwd",shell=True,stdout=subprocess.PIPE)
print(popen.stdout.read().strip())
[[email protected] /python]$ 
[[email protected] /python]$ python3 python-subprocess.py
b'/python'
[[email protected] /python]$ 
# 服务端编写

# coding=utf-8
import socket
import subprocess

server = socket.socket()
address = ("192.168.32.130", 8888)

server.bind(address)
server.listen(5)

while True:
    conn, addr = server.accept()
    while True:
        try:
            data = conn.recv(1024).decode("utf-8")

            if len(data) == 0:
                continue
            if data == "q":
                break

            # 执行命令
            obj = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE)
            cmd_result = obj.stdout.read().strip()

            # 获取一个新的bytes的对象
            result_len = bytes(str(len(cmd_result)),"utf-8")

            # 将数据全部发送给客户端,先发送长度
            conn.sendall(result_len)
            conn.recv(1024)
            conn.sendall(cmd_result)

        except Exception as e:
            break
    conn.close()
# 客户端编写

# coding=utf-8
import socket

client = socket.socket()
address = ("192.168.32.130", 8888)

client.connect(address)

while True:
    send_msg = input("请发送命令>>")

    if send_msg == "q":
        break

    client.send(bytes(send_msg,"utf-8"))

    result_len = int(str(client.recv(1024),"utf-8"))

    client.sendall(bytes("ok","utf-8"))
    data = bytes()
    while len(data) != result_len:
        recv = client.recv(1024)
        data += recv
    print(str(data,"utf-8"))

client.close()

终端打印结果

# 先运行服务端
[[email protected] /python]$ python3 socket_server.py 

# 客户端执行

请发送命令>>pwd
/python
请发送命令>>ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:B8:5C:AD  
          inet addr:192.168.32.130  Bcast:192.168.32.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:feb8:5cad/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1960879 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1227274 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2217925730 (2.0 GiB)  TX bytes:298187065 (284.3 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4398906 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4398906 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:774863790 (738.9 MiB)  TX bytes:774863790 (738.9 MiB)
请发送命令>>

猜你喜欢

转载自www.cnblogs.com/qinyujie/p/11692831.html