您的位置:首页 > 理论基础 > 计算机网络

Python的socket网络编程2.1

2017-06-23 17:37 363 查看
此节点共分2个部分  

1扩展上节课的内容.优化程序执行,添加异常补货

2.实现模拟xshell的方式 能够往服务端发送命令 并返回执行结果

使用subprocess管道实现了命令的执行返回

第一部分

######################################################

server端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''socket2 进阶'''
'''
1.使用while True 实现客户端服务端循环通信
2.异常捕获处理客户端异常关闭导致的崩溃 , 针对windows系统下
3.再次添加while True 实现循环建立连接
4.客户端无消息断开连接 , 针对linux系统下
5.此处有出现断开占用问题(egon blog) 可以修改内核参数或者在绑定地址之前判断
'''
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #理解为买电话.基于ipv4 基于流式协议tcp SOCK_DGRAM udp协议
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #注释5 重用IP地址
phone.bind(('127.0.0.1',8080)) #插卡
phone.listen(5) #开机 此处参数是指backlog 半连接池 下一篇博客解释
while True: #注释3
conn,addr=phone.accept()#等待电话接通 conn建好的连接 addr客户端地址

while True: #注释1
try: #注释2
client_msg=conn.recv(1024) #开始接收消息 此处先使用1024 每次接收的大小
if not client_msg:break #注释4
print(client_msg)
conn.send(client_msg.upper()) #将收到的消息回发回去
except ConnectionResetError: #exception 万能捕获异常
break
conn.close() #关闭连接
phone.close() #关闭手机



client端
#!/usr/bin/env python
# -*- coding:utf-8 -*-
''''''
'''
1.使用while True 实现客户端服务端循环通信
2.if not msg:continue 判断是否有消息 防止空消息问题

'''
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #等同于服务端
phone.connect(('127.0.0.1',8080)) #拨通电话 注意此处是一个元组的形式
while True:
msg=input('>>:').strip()
if not msg:continue
phone.send(msg.encode('utf-8')) #转为二进制发出去
print('ready to recv message')
back_msg=phone.recv(1024) #接收消息
print(back_msg.decode('utf-8'))
phone.close()

#===========================================================================================

第二部分  实现xshell的效果

server端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''socket2 进阶'''

'''
此处接上节内容 , 扩展支持往服务端发送命令. 并返回执行结果. 模拟xshell的执行方式
'''

'''
1.使用while True 实现客户端服务端循环通信
2.异常捕获处理客户端异常关闭导致的崩溃 , 针对windows系统下
3.再次添加while True 实现循环建立连接
4.客户端无消息断开连接 , 针对linux系统下
5.此处有出现断开占用问题(egon blog) 可以修改内核参数或者在绑定地址之前判断
'''
import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #理解为买电话.基于ipv4 基于流式协议tcp SOCK_DGRAM udp协议
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #注释5 重用IP地址
phone.bind(('127.0.0.1',8080)) #插卡
phone.listen(5) #开机 此处参数是指backlog 半连接池 下一篇博客解释
while True: #注释3
conn,addr=phone.accept()#等待电话接通 conn建好的连接 addr客户端地址

while True: #注释1
try: #注释2
cmd=conn.recv(1024) #开始接收消息 此处先使用1024 每次接收的大小
if not cmd:break #注释4
'''执行命令,获取正确输入和错误输入
如果有错误输出则输出错误
否则输出正确解决(此处正确结果为和系统相关的编码格式,此处为gbk)'''
res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,)
err=res.stderr.read()
if err:
cmd_res=err
else:
cmd_res=res.stdout.read()
conn.send(cmd_res)
except ConnectionResetError: #exception 万能捕获异常
break
conn.close() #关闭连接
phone.close() #关闭手机



client端

#!/usr/bin/env python
# -*- coding:utf-8 -*-
''''''
'''
1.使用while True 实现客户端服务端循环通信
2.if not msg:continue 判断是否有消息 防止空消息问题

'''
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #等同于服务端
phone.connect(('127.0.0.1',8080)) #拨通电话 注意此处是一个元组的形式
while True:
cmd=input('>>:').strip()
if not cmd:continue
phone.send(cmd.encode('utf-8')) #转为二进制发出去
print('ready to recv message')
cmd_msg=phone.recv(1024) #接收消息
print(cmd_msg.decode('gbk'))
phone.close()

执行先启动服务端  然后执行客户端

此时输入dir命令

ipconfig

等命令 可以正常返回执行结果

一个基本的命令发送实现了

想想还有点小激动

但是还是有2个小问题

后续篇章我们将处理 

1 粘包问题  粘包问题在以上的程序中多次执行命令就可以看到  发现执行完还是上次的执行结果. 上次的命令并没有接收完毕

2 另外还有一个问题是无法并发
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: