码迷,mamicode.com
首页 > 编程语言 > 详细

python---socket模块

时间:2016-07-07 17:28:48      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

下面是一个socket编程示例,模拟ssh远程执行命令

socket建立连接的过程,模拟成打电话过程。

 

socket_server.py

技术分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import subprocess #导入执行命令模块
#定义"电话卡"
ip_port=(127.0.0.1,9998)   #定义元组
#"买手机"
s=socket.socket()  #绑定协议,生成套接字
#"将卡和手机绑定"
s.bind(ip_port)   #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式
#"开机"
s.listen(5)   #定义最大可以挂起连接数
#等待电话
while True:  #用来重复接收新的连接
    conn,addr=s.accept()   #接收客户端连接请求,返回conn(相当于一个特定连接),addr是客户端ip+port
    #收消息
    while True:  #用来基于一个连接重复收发消息
           #捕捉客户端异常关闭(ctrl+c)
           #如果客户端异常关闭(没有执行close()),导致连接异常,服务端也会异常
           try:
                recv_data=conn.recv(1024)  #收消息,收到后阻塞,接收大小介于1024和8192之间
                #print(len(recv_data))
                #客户端如果正常退出(执行了close()),服务端recv函数将收到空消息,这时server端也退出
                if len(recv_data) == 0:
                    print("客户端正常退出")
                    break

                p=subprocess.Popen(str(recv_data,encoding=utf8),shell=True,stdout=subprocess.PIPE)   #执行系统命令
                res=p.stdout.read()  #获取标准输出
                #如果执行命令错误,标准输出为空,必须判断标准输出是否为空,如果为空send_data就为‘cmd err‘,不然会导致客户端recv()阻塞
                if len(res) == 0:
                    send_data=cmd err
                else:
                    #windows平台命令的标准输出是gbk编码,需要转换,先转换成字符串(因为各种编码中字符串是一样的)
                    send_data=str(res,encoding=gbk)
                #再转换成utf8,注意python3中需要转换成字节才能发送,python2中能直接发送字符串
                send_data=bytes(send_data,encoding=utf8)


                #解决粘包问题
                ready_tag=Ready|%s %len(send_data)
                conn.send(bytes(ready_tag,encoding=utf8)) #告诉client端数据长度
                feedback=conn.recv(1024)  #接收确认信息
                feedback=str(feedback,encoding=utf8)  #接收的也是字节,需要转换成字符串

                if feedback.startswith(Start):   #如果确认信息是以"Start"开头
                    conn.send(send_data)  #则发送命令的执行结果
           except Exception:
            print("客户端异常退出")
            break
    #"挂电话"
    conn.close()
View Code

 

socket_client.py

技术分享
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port=(127.0.0.1,9998)
#"买手机"
s=socket.socket()
#"拨号"
s.connect(ip_port)  #连接服务端,如果服务端已经存在一个好的连接,那么挂起

while True:     #基于connect建立的连接来循环发送消息
    send_data=input(">>: ").strip()
    if send_data == exit:break
    if len(send_data) == 0:continue
    s.send(bytes(send_data,encoding=utf8))

    #解决粘包问题
    ready_tag=s.recv(1024)    #收取带数据长度的字节:Ready|9998
    ready_tag=str(ready_tag,encoding=utf8)
    if ready_tag.startswith(Ready):    #Ready|9998
        msg_size=int(ready_tag.split(|)[-1])  #获取待接收数据长度
    start_tag=Start
    s.send(bytes(start_tag,encoding=utf8)) #发送确认信息"Start"

    #基于已经收到的待接收数据长度,循环接收数据
    recv_size=0
    recv_msg=b‘‘    #表示空字节
    while recv_size < msg_size:
        recv_data=s.recv(1024)
        recv_msg+=recv_data
        recv_size+=len(recv_data)
        print(MSG SIZE %s RECE SIZE %s %(msg_size,recv_size))

    print(str(recv_msg,encoding=utf8))
    #挂电话
s.close()
View Code

 

python---socket模块

标签:

原文地址:http://www.cnblogs.com/zhoufeng1989/p/5650581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!