socket ssh客户端服务器,ftp客户端,服务端【老男孩笔记】

socket ssh服务端

import socket, os

# 创建套接字
server = socket.socket()
# 绑定端口
server.bind(('localhost', 7890))
# 监听
server.listen()

while True:
    conn, addr = server.accept()
    # 打印客户信息
    print("new conn:", addr)
    # 接收客户信息
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令",data)
        cmd_res = os.popen(data.decode()).read() # 接收字符串,执行结果也是字符串
        print("send start", len(cmd_res))
        # 抛出异常
        if len(cmd_res) == 0:
            cmd_res = 'cmd has no output...'
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()

socket ssh 客户端

# client

import socket
# 创建套接字
client = socket.socket()
# 连接
client.connect(("localhost", 7890))

while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res = client.recv(1024)
    
    print(cmd_res.decode("utf-8"))


client.close()

以上有一个问题,当发送数据超过1024字节就会进入缓冲区,无法显示

改进版服务端

import socket, os

server = socket.socket()
server.bind(('localhost', 7890))

server.listen()

while True:
    conn, addr = server.accept()
    print("new conn:", addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令",data)
        cmd_res = os.popen(data.decode()).read() # 接收字符串,执行结果也是字符串
        print("send start", len(cmd_res))
        if len(cmd_res) == 0:
            cmd_res = 'cmd has no output...'
        conn.send( str(len(cmd_res.encode())).encode("utf-8") ) # 告知客户端,发送数据大小
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()

改进客户端

# client

import socket

client = socket.socket()

client.connect(("localhost", 7890))

while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(1024) # 接收命令结果的长度
    print("命令结果大小:", cmd_res_size)
    
    receive_size = 0
    receive_data = b''
    while receive_size < int(cmd_res_size.decode()): # 是二进制
        
        data = client.recv(1024)
        
        receive_size += len(data) # 每次收到的有可能小于1024所以必须用len判断
        # print(data.decode())
        receive_data += data
    # print(cmd_res_size.decode("utf-8"))

    else:
        print("cmd res receive done...",receive_size)
        print(receive_data.decode())
client.close()

处理粘包

import socket, os

server = socket.socket()
server.bind(('localhost', 7890))

server.listen()

while True:
    conn, addr = server.accept()
    print("new conn:", addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令",data)
        cmd_res = os.popen(data.decode()).read() # 接收字符串,执行结果也是字符串
        print("send start", len(cmd_res))
        if len(cmd_res) == 0:
            cmd_res = 'cmd has no output...'
        conn.send( str(len(cmd_res.encode())).encode("utf-8") ) # 告知客户端,发送数据大小
        client_ack = conn.recv(1024) # 客户二次确认处理粘包
        print("ack from client", client_ack)
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()
# client

import socket

client = socket.socket()

client.connect(("localhost", 7890))

while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(1024) # 接收命令结果的长度
    print("命令结果大小:", cmd_res_size)
    client.send("准备好接收了".encode("utf-8"))
    
    receive_size = 0
    receive_data = b''
    while receive_size < int(cmd_res_size.decode()): # 是二进制
        
        data = client.recv(1024)
        
        receive_size += len(data) # 每次收到的有可能小于1024所以必须用len判断
        # print(data.decode())
        receive_data += data
    # print(cmd_res_size.decode("utf-8"))

    else:
        print("cmd res receive done...",receive_size)
        print(receive_data.decode())
client.close()

ftp server

  1. 读取文件名
  2. 检测文件是否存在
  3. 打开文件
  4. 检测文件大小
  5. 发送文件大小给客户端
  6. 等待客户确认
  7. 开始边读边发数据
  8. 校验码

无校验码服务端:

# ftp server

import socket, os, hashlib

server = socket.socket()
server.bind(('localhost', 7890))

server.listen()

while True:
    conn, addr = server.accept()
    print("new conn:", addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        cmd, filename = data.decode().split()
        print(filename)
        if os.path.isfile(filename): # 判断是否是一个文件
            f = open(filename, "rb")
            m = hashlib.md5()
            # 获取文件大小
            file_size = os.stat(filename).st_size
            conn.send( str(file_size).encode() )
            conn.recv(1024) 
            # 循环发送数据
            for line in f:
               # m.update(line)
                conn.send(line)
           # print("file md5", m.hexdigest())    
            f.close()
        print("send done")
server.close()

无校验码客户端

#ftp client

import socket

client = socket.socket()

client.connect(("localhost", 7890))

while True:
    cmd = input(">>:").strip()
    print(len(cmd))
    if len(cmd) == 0: continue # 可以发空字节
    
    if cmd.startswith("get"): # 用于检查字符串是否是以指定子
        # 字符串开头,如果是则返回 True,否则返回 False
        client.send(cmd.encode())
        print("encode后:", type(cmd))
        # 接收信息
        server_response = client.recv(1024)
        print("servr response:", server_response)
        client.send(b'ready to recv file')
        file_total_size = int(server_response.decode())
        receive_size = 0
        filename = cmd.split()[1]
        f = open(filename + "new", 'wb')
        while receive_size < file_total_size:
            data = client.recv(1024)
            receive_size += len(data)
            f.write(data)
            # print(file_total_size, receive_size)
        else:
            print("file recv done", receive_size, file_total_size)
            f.close()
client.close()

最终版ftp_client

#ftp client

import socket
import hashlib


client = socket.socket()

client.connect(("localhost", 7890))

while True:
    cmd = input(">>:").strip()
    print(len(cmd))
    if len(cmd) == 0: continue # 可以发空字节
    
    if cmd.startswith("get"): # 用于检查字符串是否是以指定子
        # 字符串开头,如果是则返回 True,否则返回 False
        client.send(cmd.encode())
        print("encode后:", type(cmd))
        # 接收信息
        server_response = client.recv(1024)
        print("servr response:", server_response)
        client.send(b'ready to recv file')
        file_total_size = int(server_response.decode())
        receive_size = 0
        filename = cmd.split()[1]
        f = open(filename + "new", 'wb')
        m = hashlib.md5()    
        
        while receive_size < file_total_size:
            # 解决粘包问题,这样通过判断,发多少收多少
            if file_total_size - receive_size > 1024: # 重复回收
                size = 1024
            else:
                size = file_total_size - receive_size
                print("last receive:", size)
            data = client.recv(size)
            receive_size += len(data)
            m.update(data)
            f.write(data)
            f.write(data)
            # print(file_total_size, receive_size)
            
        else:
            new_file_md5 = m.hexdigest()
            print("file recv done", receive_size, file_total_size)
            f.close()
            server_file_md5 = client.recv(1024)
            print("server file md5:", server_file_md5)
            print("client file md5:", new_file_md5)
client.close()

最终版ftp_server

# ftp server

import socket, os, hashlib

server = socket.socket()
server.bind(('localhost', 7890))

server.listen()

while True:
    conn, addr = server.accept()
    print("new conn:", addr)
    while True:
        print("等待新指令")
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        cmd, filename = data.decode().split()
        print(filename)
        if os.path.isfile(filename): # 判断是否是一个文件
            f = open(filename, "rb")
            m = hashlib.md5()
            # 获取文件大小
            file_size = os.stat(filename).st_size
            conn.send( str(file_size).encode() )
            conn.recv(1024) 
            # 循环发送数据
            for line in f:
                m.update(line)
                conn.send(line)
            print("file md5", m.hexdigest())    
            f.close()
            conn.send(m.hexdigest().encode()) #发送md5
        print("send done")
server.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值