Day32、基于tcp通信的套接字,连接与通信循环,粘包问题,远程控制

一、基于tcp通信的套接字程序

服务端:

from socket import *

# 服务端必须满足至少三点:
# 1.绑定一个固定的ip和port
# 2.一直对外提供服务,稳定运行
# 3.能够支持并发
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 9555))
server.listen(5)

client, addr = server.accept()
data = client.recv(1024)
print(data.decode('utf-8'))
client.send(data.upper())

client.close()
server.close()

客户端:

from socket import *
client = socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',9555))

msg = input('>>>:').strip()
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data)

client.close()

二、修改bug + 通信循环 + 连接循环

  上述存在客户端退出时服务端即会崩溃的bug,而且无法实现用户的多次输入,以及服务端无法一直对外服务的问题,对此进行修改

服务端:

from socket import *

server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8081))
server.listen(5)

# 链接循环
while True:
    conn, client_addr = server.accept()
    print(client_addr)

    # 通信循环
    while True:
        try:
            data = conn.recv(1024)
            if len(data) == 0: break  # 针对linux系统
            print('-->收到客户端的消息: ', data)
            conn.send(data.upper())
        except ConnectionResetError:
            break

    conn.close()

server.close()

客户端:

from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8081))

# 通信循环
while True:
    msg=input('>>: ').strip() #msg=''
    if len(msg) == 0:continue
    client.send(msg.encode('utf-8')) #client.send(b'')
    # print('has send')
    data=client.recv(1024)
    # print('has recv')
    print(data)

client.close()

三、粘包问题解决方案

服务端:

import socket
import subprocess
import struct
import json

IP = '127.0.0.1'
PORT = 8383
ADDRESS = (IP, PORT)
BUFSIZE = 1024

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind(ADDRESS)

server.listen(5)
tag = True
while tag:
    conn, addr = server.accept()
    while tag:
        try:
            data = conn.recv(BUFSIZE)
            if not data:
                print('服务端断开。。。。')
                break
            # 获取sub对象
            res = subprocess.Popen(data.decode("utf-8"),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            print('>>>>', data.decode('utf-8'))
            # 成功的结果
            stdout = res.stdout.read()
            # 失败的结果
            stderr = res.stderr.read()

            # 1.制作报头
            header_dic = {
                'filename': 'a.txt',
                'md5': 'sd7a86d87sad6as',
                'total_size': len(stdout) + len(stderr)
            }
            header_json = json.dumps(header_dic)
            header_bytes = header_json.encode('utf-8')

            # 2.先发送报头长度
            conn.send(struct.pack('i', len(header_bytes)))

            # 3.再发送报头
            conn.send(header_bytes)

            # 4.最后发送数据
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()
server.close()

客户端:

import socket
import struct
import json
IP = '127.0.0.1'
PORT = 8383
ADDRESS = (IP, PORT)
BUFSIZE = 1024

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(ADDRESS)
while True:

    msg = input('>>>')
    if len(msg) == 0: continue
    client.send(msg.encode('utf-8'))

    # 1.先获取报头长度
    header_size = struct.unpack('i',client.recv(4))[0]

    #2.在获取报头
    header_bytes=client.recv(header_size)
    header_json=header_bytes.decode('utf-8')
    header_dic=json.loads(header_json)
    print(header_json)
    total_size=header_dic['total_size']

    # 3.在获取真正数据
    cmd_res=b''
    recv_size=0
    while recv_size<total_size:
        data=client.recv(1024)
        recv_size+=len(data)
        cmd_res+=data
    print(cmd_res.decode('gbk'))

client.close()

四、远程控制

服务端:

from socket import *

import subprocess

 

# 服务器必须满足至少三点

# 1. 绑定一个固定的ip和port

# 2. 一直对外提供服务,稳定运行

# 3. 能够支持并发

 

server = socket(AF_INET, SOCK_STREAM)

 

server.bind(('192.168.13.235', 8080))

 

server.listen(5)

 

# 链接循环

while True:

    conn, client_addr = server.accept()

 

    # 通信循环

    while True:

        # 捕捉异常防止客户端断开链接导致服务器报错

        try:

            data = conn.recv(1024)

 

            

            obj = subprocess.Popen(data.decode('utf-8'),

                                   shell=True,

                                   stdout=subprocess.PIPE,

                                   stderr=subprocess.PIPE

                                   )

            stdout = obj.stdout.read()

            stderr = obj.stderr.read()

 

            conn.send(stdout)

 

        except ConnectionResetError:

            break

 

    conn.close()

server.close()
View Code

客户端:

from socket import *

import subprocess

 

# 服务器必须满足至少三点

# 1. 绑定一个固定的ip和port

# 2. 一直对外提供服务,稳定运行

# 3. 能够支持并发

 

server = socket(AF_INET, SOCK_STREAM)

 

server.bind(('192.168.13.235', 8080))

 

server.listen(5)

 

# 链接循环

while True:

    conn, client_addr = server.accept()

 

    # 通信循环

    while True:

        # 捕捉异常防止客户端断开链接导致服务器报错

        try:

            data = conn.recv(1024)

 

            

            obj = subprocess.Popen(data.decode('utf-8'),

                                   shell=True,

                                   stdout=subprocess.PIPE,

                                   stderr=subprocess.PIPE

                                   )

            stdout = obj.stdout.read()

            stderr = obj.stderr.read()

 

            conn.send(stdout)

 

        except ConnectionResetError:

            break

 

    conn.close()

server.close()
View Code
原文地址:https://www.cnblogs.com/Mister-JH/p/9580647.html