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

python 网络编程:socket和select实现伪并发

时间:2016-07-11 16:51:54      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

上节地址:Python网络编程:socket

先补充点内容:

一、send和sendall区别

send,sendall
        ret = send(‘safagsgdsegsdgew‘) #send 发送完成后会有一个返回值,告知发送了多少,并不一定会把数据全部发送过去。
        sendall:内部调用send,将数据全部发送完为止。
        因此我们使用时最好使用sendall
二、粘包
粘包问题需要理解recv()的使用,我们定义接收值的时候会写recv(1024)表示一次接收1024字节,但是有时候接收的数据大于1024字节,这样socket默认变不发送了,等待下次接收其他命令时在将上次没有发送完的数据继续发送过去,这样就形成了粘包问题。对于粘包,可以在正式收发数据之前先判断下数据的大小,然后分片发送。下面是利用socket和subprocess实现的类似cmd的程序。
技术分享
#!/usr/bin/env python
# _*_ coding:utf_8 _*_
import socket
ip_port=(127.0.0.1,9002)
s = socket.socket()
s.connect(ip_port)
while True:
    send_data = input(>>: ).strip()
    if len(send_data) == 0:continue
    if send_data == exit:break
    s.send(bytes(send_data,encoding=utf-8))
    #解决粘包问题
    ready_tag = s.recv(1024)  #收取待发送字节的长度
    ready_tag=str(ready_tag,encoding=utf8)
    if ready_tag.startswith(Ready):  #数据包格式为Ready|9124
        msg_size=int(ready_tag.split(|)[-1])
    start_tag = Start
    s.sendall(bytes(start_tag,encoding=utf8))  #发送消息,表示开始传输
    recv_size = 0
    #print(msg_size)
    recv_msg = b‘‘
    while recv_size < msg_size:
        recv_data = s.recv(1024)
        recv_msg+=recv_data
        recv_size+=len(recv_data)
    print(str(recv_msg,encoding=utf8))
    #收消息
    # recv_data=s.recv(1024)
    # print(str(recv_data,encoding=‘utf-8‘))

s.close()
socket_client
技术分享
#!/use/bin/env python
#_*_ coding:utf_8 _*_
import socket
import subprocess
ip_addr=(127.0.0.1,9002)
s=socket.socket()   #创建对象
s.bind(ip_addr)     #绑定连接地址
s.listen(5)         #设置监听主机数
while True:
    conn,addr=s.accept()
    i = 0
    while True:
        print(i)
        try:
            recv_data = conn.recv(1024)
            print(------0)
            #print(str(recv_data,encoding=‘utf-8‘))
            if len(recv_data) == 0:break
            #执行系统命令
            p=subprocess.Popen(str(recv_data,encoding=utf-8),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)#执行系统命令,windows平台命令的标准输出是gbk编码,需要转换
            res = p.stdout.read() #获取标准输出
            if len(res) == 0:   #执行错误命令,send_data为空
                send_data = str(p.stderr.read(),encoding=utf-8)
            else:
                send_data=str(res,encoding=gbk)
            send_data=bytes(send_data,encoding=utf-8)    #要发送的数据

            #判断粘包
            ready_tag=Ready|%s %len(send_data)
            conn.send(bytes(ready_tag,encoding=utf8)) #发送数据长度
            feedback=conn.recv(1024)  #接收确认信息
            feedback=str(feedback,encoding=utf8)
            if feedback.startswith(Start):
                print(send_data)
                conn.sendall(send_data)  #发送命令的执行结果
            #conn.sendall(send_data)
            print(succeed)
            i+=1



        except Exception:
            break
    conn.close()
socket cmd

 

 

python 网络编程:socket和select实现伪并发

标签:

原文地址:http://www.cnblogs.com/ernest-zhang/p/5660590.html

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