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
- 读取文件名
- 检测文件是否存在
- 打开文件
- 检测文件大小
- 发送文件大小给客户端
- 等待客户确认
- 开始边读边发数据
- 校验码
无校验码服务端:
# 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()