python day9
python 第九天
-----------------------------------------------------------------------------------------------------
socket网络编程
# 服务器端
1.IP,端口
2.监听
3.连接池
4.收,发
# 客户端
1.连接服务器端IP,端口
2.发,收
一、socket单线程
1.socket 简单使用,一次性程序
----------server.py
"""
建立服务器连接六个步骤
1.创建socket对象
2.socket绑定IP端口
3.启动建立连接监听
4.阻塞等待客户请求
5.处理阶段,先收后发
6.传输结束
python3特点
1.传的数据类型默认是bytes
2.recv 接收需要将bytes转成字符串打印
3.sendall 发送需要将内容转成bytes对方才能识别
4.有两个阻塞 accept和recv
"""
import socket
ip_port = ('0.0.0.0',8001)
sk = socket.socket() #创建socket
sk.bind(ip_port) #绑定端口IP
sk.listen(5) #启动监听,允许5个等待
while True:
print("server waiting.......")
conn,addr = sk.accept() #阻塞等待客户请求
client_data = conn.recv(1024) #收数据
print(str(client_data,'utf8')) #转成字符串输出本屏打印
conn.sendall(bytes("不要回答",'utf8')) #发数据
conn.close() #关闭连接
-------------client.py
"""
socket客户端连接4个步骤
1.创建socket
2.绑定端口IP( 指定服务器端)
3.处理数据,先发后收
4.关闭连接
python3特点
1.传的数据类型默认是bytes
2.recv 接收需要将bytes转成字符串打印
3.sendall 发送需要将内容转成bytes对方才能识别
4.有两个阻塞 accept和recv
"""
import socket
ip_port = ('127.0.0.1',9000)
sk = socket.socket() #创建socket
sk.connect(ip_port) #绑定端口IP
sk.sendall(bytes("我要占领地球",'utf8')) #发数据
server_reply = sk.recv(1024) #收数据
print(str(server_reply,'utf8')) #把接收的数据打印到本地屏幕
sk.close() #关闭连接
----测试
1.先运行server.py
2.再运行client.py
----结果
# server端
server waiting.......
我要占领地球 # 客户端发来的数据
server waiting.......
# client端
不要回答 #服务器回的数据
2.socket 实现客户端可写入发什么内容 服务端就返回什么内容
-----server.py
import socket
ip_port = ('0.0.0.0',9998)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print ('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print (str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答',encoding='utf8'))
while True:
try:
client_data = conn.recv(1024)
print (str(client_data,encoding='utf8'))
except Exception:
print("client closed,break")
break
conn.send(client_data)
#server_response = input("\033[32m>>:\033[0m").strip()
#conn.send(bytes(server_response,'utf8'))
conn.close()
------client.py
import socket
ip_port = ('127.0.0.1',9998)
sk = socket.socket()
sk.connect(ip_port)
sk.sendall(bytes('请求占领地球',encoding='utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,'utf8'))
while True:
user_input = input(">>:").strip()
sk.send(bytes(user_input,'utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,encoding='utf-8'))
sk.close()
3.socket 客户端发小写,服务端回大写
# ----------for windows
----server.py
import socket
ip_port = ('127.0.0.1',9995)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print ('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print (str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答','utf8'))
while True:
try:
client_data = conn.recv(1024)
send_data=client_data.upper()
print (str(client_data,'utf8'))
except Exception:
print("client closed,break")
break
conn.send(send_data)
#server_response = input("\033[32m>>:\033[0m").strip()
#conn.send(bytes(server_response,'utf8'))
conn.close()
-----client.py
import socket
ip_port = ('127.0.0.1',9995)
sk = socket.socket()
sk.connect(ip_port)
sk.sendall(bytes('请求占领地球','utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,'utf8'))
while True:
user_input = input(">>:").strip()
sk.send(bytes(user_input,'utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,'utf8'))
sk.close()
-------结果
# client端
不要回答,不要回答,不要回答
>>:jkfjsalfdsaf
JKFJSALFDSAF
>>:jksfjdsalfsa
# server端
server waiting...
请求占领地球
jkfjsalfdsaf
jksfjdsalfsa
# -----------for linux
------server.py
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print ('server waiting...')
conn,addr = sk.accept()
client_data = conn.recv(1024)
print (str(client_data,'utf8'))
conn.sendall(bytes('不要回答,不要回答,不要回答','utf8'))
while True:
client_data = conn.recv(1024)
print (str(client_data,'utf8'))
if not client_data:break
conn.send(client_data)
conn.close()
------client.py
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port)
sk.sendall(bytes('请求占领地球','utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,'utf8'))
while True:
user_input = input(">>:").strip()
sk.send(bytes(user_input,'utf8'))
server_reply = sk.recv(1024)
print (str(server_reply,'utf8'))
sk.close()
二、多线程socketserver
# socketserver 程序默认已封装了多线程,所以它就是一个多线程的网络编程模块
1.socketserver 写什么输出什么,输出大写
-------server.py
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self): #必须是此函数名,因为socketserver的类中的方法是此名
# print self.request,self.client_address,self.server
#conn
self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8"))
while True:
data = self.request.recv(1024)
print("-->",len(data))
if len(data) == 0:break
print("[%s] says:%s" % (self.client_address,data.decode() ))
self.request.sendall(data.upper())
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),MyServer) #把MyServer载入多线程
server.serve_forever()
------client.py
import socket
ip_port=('127.0.0.1',8009)
s=socket.socket()
s.connect(ip_port)
welcome_msg = s.recv(1024)
print("from server:",welcome_msg.decode())
while True:
send_data=input(">>: ").strip()
if len(send_data) == 0:continue
s.send(bytes(send_data,encoding='utf8'))
#收消息
recv_data=s.recv(1024)
print(str(recv_data,encoding='utf8'))
s.close()
-------结果
# 客户端1
from server: 欢迎致电 10086,请输入1xxx,0转人工服务.
>>: jflksjflsa
JFLKSJFLSA
# 客户端2
from server: 欢迎致电 10086,请输入1xxx,0转人工服务.
>>: fsafdjsdfksaf
FSAFDJSDFKSAF
# server端
--> 10
[('127.0.0.1', 54637)] says:jflksjflsa
--> 13
[('127.0.0.1', 54637)] says:jskjfdsljfsaf
2.socketserver 基于socket实现类ssh远程执行命令
#解决粘包问题后的程序
-------server.py
import socketserver
import subprocess
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# print self.request,self.client_address,self.server
self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8"))
while True:
data = self.request.recv(1024)
if len(data) == 0:break
print("[%s] says:%s" % (self.client_address,data.decode() ))
#self.request.sendall(data.upper())
cmd = subprocess.Popen(data.decode(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
cmd_res =cmd.stdout.read()
if not cmd_res:
cmd_res = cmd.stderr.read()
if len(cmd_res) == 0: #cmd has not output
cmd_res = bytes("cmd has output",encoding="utf-8")
self.request.send(cmd_res )
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('0.0.0.0',8009),MyServer)
server.serve_forever()
-------client.py
import socket
ip_port=('172.16.0.2',8009)
s=socket.socket()
s.connect(ip_port)
welcome_msg = s.recv(1024)
print("from server:",welcome_msg.decode())
while True:
send_data=input(">>: ").strip()
if len(send_data) == 0:continue
s.send(bytes(send_data,encoding='utf8'))
recv_data=s.recv(1024)
print(str(recv_data,encoding='utf8'))
s.close()
---------结果
# server端
[('172.16.0.111', 52119)] says:ifconfig
[('172.16.0.111', 52119)] says:ls
[('172.16.0.111', 52119)] says:exit
# client端
>>: ls
1.png
1.py
aa.py
>>: ifconfig
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.0.2 netmask 255.0.0.0 broadcast 172.255.255.255
>>: exit #触发解决粘包打印
cmd has output
3.socketserver 实现FTP功能
-------server.py
import socketserver,json
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
# print self.request,self.client_address,self.server
self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8"))
while True:
data = self.request.recv(1024)
if len(data) == 0:break
print("data", data)
print("[%s] says:%s" % (self.client_address,data.decode() ))
task_data = json.loads( data.decode() )
task_action = task_data.get("action")
if hasattr(self, "task_%s"%task_action):
func = getattr(self,"task_%s" %task_action)
func(task_data)
else:
print("task action is not supported",task_action)
def task_put(self,*args,**kwargs):
print("---put",args,kwargs)
filename = args[0].get('filename')
filesize = args[0].get('file_size')
server_response = {"status":200}
self.request.send(bytes( json.dumps(server_response), encoding='utf-8' ))
f = open(filename,'wb')
recv_size = 0
while recv_size < filesize: #接收为0,以下循环加,最终等于文件大小,即接收完成
data = self.request.recv(4096)
f.write(data)
recv_size += len(data) #循环加读数据长度
print('filesize: %s recvsize:%s' % (filesize,recv_size))
print("file recv success")
f.close()
if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('0.0.0.0',8009),MyServer) #把MyServer载入多线程
server.serve_forever()
------client.py
import socket
import os ,json
ip_port=('192.168.11.150',8009)
s=socket.socket()
s.connect(ip_port)
welcome_msg = s.recv(1024)
print("from server:",welcome_msg.decode())
while True:
send_data=input(">>: ").strip()
if len(send_data) == 0:continue
cmd_list = send_data.split()
if len(cmd_list) <2:continue
task_type = cmd_list[0]
if task_type == 'put':
abs_filepath = cmd_list[1]
if os.path.isfile(abs_filepath):
file_size = os.stat(abs_filepath).st_size
filename = abs_filepath.split("\\")[-1]
print('file:%s size:%s' %(abs_filepath,file_size))
msg_data = {"action":"put",
"filename":filename,
"file_size":file_size}
s.send( bytes(json.dumps(msg_data),encoding="utf-8") )
server_confirmation_msg = s.recv(1024)
confirm_data = json.loads(server_confirmation_msg.decode())
if confirm_data['status'] ==200:
print("start sending file ",filename)
f = open(abs_filepath,'rb')
for line in f:
s.send(line)
print("send file done ")
continue
else:
print("\033[31;1mfile [%s] is not exist\033[0m" % abs_filepath)
continue
else:
print("doesn't support task type",task_type)
continue
#s.send(bytes(send_data,encoding='utf8'))
#收消息
recv_data=s.recv(1024)
print(str(recv_data,encoding='utf8'))
s.close()
---------结果
# client端
from server: 欢迎致电 10086,请输入1xxx,0转人工服务.
>>: put D:\Downloads\1.txt
file:D:\Downloads\1.txt size:28
start sending file 1.txt
send file done
# server端
data b'{"filename": "1.txt", "action": "put", "file_size": 28}'
[('172.16.0.111', 52225)] says:{"filename": "1.txt", "action": "put", "file_size": 28}
---put ({'action': 'put', 'filename': '1.txt', 'file_size': 28},) {}
filesize: 28 recvsize:16
filesize: 28 recvsize:28
file recv success