Python 提供了两个级别访问的网络服务。:
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
客户端
import socket
def main():
client=socket.socket()#创建套接字,第二个参数type: 套接字类型可以根据是面向连接的还是非连接分为SOCK_STREAM或SOCK_DGRAM
client.connect(('127.0.0.1',7000))#连接服务端的ip和端口
client.send('Hello World'.encode())#python3发送数据,只能发送字节数据
data=client.recv(1024)#最多接收1024个字节,data是字节类型
print('recv:',data.decode())#将字节类型变为str类型
client.close()
if __name__ == "__main__":
main()
'''
结果为:
recv: 你好世界!
'''
服务端
import socket
def main():
server=socket.socket()#创建套接字
server.bind(('127.0.0.1',7000))#绑定监听端口
server.listen(5)#开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
conn,addr=server.accept()#被动接受TCP客户端连接,(阻塞式)等待连接的到来,返回客户端连接和客户端地址
print('客户端连接进来了,它的地址是:%s:%s'%addr)
data=conn.recv(1024)#接收TCP数据,数据以字节形式返回,最多接收1024个字节
print('recv:',data.decode())#将字节转化成str
conn.send('你好世界!'.encode())#将字符串转换成bytes,python3只能发送字节类型
server.close()
if __name__ == "__main__":
main()
'''
结果:
客户端连接进来了,它的地址是:127.0.0.1:56580
recv: Hello World
'''
ssh服务端
import socket
import os
def main():
server=socket.socket()
server.bind(('127.0.0.1',7000))
server.listen(5)
while True:
conn,addr=server.accept()
print('客户端连接进来了,它的地址是:%s:%s'%addr)
while True:
data=conn.recv(1024).decode()
if data=='exit':
print('客户端已断开连接')
conn.send(str(0).encode())
break
print('执行指令:',data)
cmd_res=os.popen(data).read()#执行命令返回字符串
if not cmd_res:
cmd_res='错误的命令'
conn.send(str(len(cmd_res.encode())).encode())#发送执行命令产生结果的数据大小
code=conn.recv(1024).decode()#接收从客户端发来代码,如果为1,代表客户端接收成功,防止发送数据过快,数据粘在一起,产生粘包
conn.send(cmd_res.encode())
server.close()
if __name__ == "__main__":
main()
ssh客户端
import socket
def main():
client=socket.socket()
client.connect(('127.0.0.1',7000))
while True:
cmd=input('>>:').strip()
if len(cmd)==0:continue
client.send(cmd.encode())
cmd_res_size=int(client.recv(1024).decode())#接收命令结果的字节长度
if cmd_res_size==0:break#返回0代表断开连接
received_size=0
client.send(str(1).encode())#防止粘包
while received_size!=cmd_res_size:
received_data=client.recv(1024)
received_size+=len(received_data)
print(received_data.decode())
client.close()
if __name__ == "__main__":
main()
文件客户端
import socket
import hashlib
def main():
client=socket.socket()
client.connect(('127.0.0.1',7000))
while True:
cmd=input('>>:').strip()
if len(cmd)==0:continue
if cmd.startswith('get'):
client.send(cmd.encode())
file_size=int(client.recv(1024).decode())#接收文件大小
client.send('ready to recv file'.encode())#向服务端发送确认
received_size=0
f=open('a_'+cmd.split()[1],'wb')
m=hashlib.md5()
while received_size!=file_size:
size=0
#防止粘包
if file_size-received_size>1024:
size=1024
else:size=file_size-received_size
received_data=client.recv(size)
m.update(received_data)
received_size+=len(received_data)
f.write(received_data)
else:
received_md5=client.recv(1024).decode()
if m.hexdigest()==received_md5:
print('file recv done')
break
client.close()
if __name__ == "__main__":
main()
文件服务端
import socket
import os
import hashlib
def main():
server=socket.socket()
server.bind(('127.0.0.1',7000))
server.listen(5)
while True:
conn,addr=server.accept()
print('客户端连接进来了,它的地址是:%s:%s'%addr)
while True:
data=conn.recv(1024).decode()
if not data:
print('客户端已断开连接')
break
filename=data.split()[1]
print('文件名是:',filename)
if os.path.isfile(filename):
f=open(filename,'rb')
file_size=os.stat(filename).st_size#获取文件大小
conn.send(str(file_size).encode())#发送文件大小
acg=conn.recv(1024)#等待客户端确认
m=hashlib.md5()
for line in f:
m.update(line)#MD5加密,line是bytes类型
conn.send(line)
conn.send(m.hexdigest().encode())
f.close()
break
break
server.close()
if __name__ == "__main__":
main()
socketserver是标准库中一个高级别的模块,用于简化网络客户与服务器的实现。
socketserver服务端
import socketserver
class MyTcpHandler(socketserver.BaseRequestHandler):#每接收一个请求则实例化这个类
def handle(self):#重写handle方法
print('客户端的ip地址是:%s:%s' % self.client_address)
while True:
try:
self.data=self.request.recv(1024).decode().strip()
print('客户端发送的数据是:',self.data)
self.request.send('Hello World!'.encode())
except ConnectionResetError as e:
print('客户端已断开连接')
break
def main():
HOST,PORT='127.0.0.1',7000
server=socketserver.ThreadingTCPServer((HOST,PORT),MyTcpHandler)#支持多并发
server.serve_forever()
if __name__ == "__main__":
main()
socketserver客户端
import socket
def main():
client=socket.socket()
client.connect(('127.0.0.1',7000))
while True:
cmd=input('>>:').strip()
client.send(cmd.encode())
data=client.recv(1024).decode()
print(data)
if __name__ == "__main__":
main()
paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。
import paramiko
def main():
#创建ssh对象
ssh=paramiko.SSHClient()
#允许连接不在know_hosts文件中的主机。
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
#连接服务器
ssh.connect(
hostname='192.168.244.128',
port=22,
username='用户名',
password='密码'
)
#执行命令
stdin,stdout,stderr=ssh.exec_command('ifconfig')
#获取命令结果
result=stdout.read()
print(result.decode())
if __name__ == "__main__":
main()
import paramiko
def main():
transport = paramiko.Transport(('hostname',22))
transport.connect(username='用户名',password='密码')
sftp = paramiko.SFTPClient.from_transport(transport)
# 将1.txt上传至服务器 /tmp/1.txt
sftp.put('1.txt', '/tmp/1.txt')
# 将2.txt下载到本地
sftp.get('2.txt', '/tmp/2.txt')
transport.close()
if __name__ == "__main__":
main()