V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
moxiaowei
V2EX  ›  Python

socket 接收数据的问题

  •  
  •   moxiaowei · 2019-05-24 09:15:36 +08:00 · 1985 次点击
    这是一个创建于 2012 天前的主题,其中的信息可能已经有所发展或是发生改变。
    def recvMessage(self, sockHandle):#读取来自客户端的数据
            strings = b""
            getNullTime = 0
            client = self.dictSocketHandle[sockHandle]
            num = 1
            totalLen = 0
            while True:
                try:
                    print("第"+str(num)+"次读取数据")
                    data = client.recv(1024)  # 这儿如果没有拿够 1024 个字节的数据,那么会循环回来拿,但是,如果发现没有数据能拿到,socket 会自动中止,扔出一个异常,代码就结束执行,所以需要 try 一下。
                    print(len(data))
                    totalLen += len(data)
                    if len(data) == 0:  # 通道断开或者 close 之后,就会一直收到空字符串。 而不是所谓的-1 或者报异常。这个跟 C 和 java 等其他语言很不一样。
                        self.epollHandle.modify(sockHandle, select.EPOLLHUP | select.EPOLLET)
                        break
                    # print("本次接收到的数据........", data)
                    strings = strings + data
    
                    getNullTime = 0
    
                except IOError as err:
                    if err.errno == 11:  # 发生 Resource temporarily unavailable 错误 错误码为 11,意为:数据尚未准备好,需要等待
                        if getNullTime >= 3:
                            break
                        else:
                            getNullTime = getNullTime + 1
                            print("第" + str(getNullTime) + "次获取到空数据,继续尝试中.......")
                    else:
                        print("读取数据,未知 IO 错误")
                        self.epollHandle.modify(sockHandle, select.EPOLLHUP | select.EPOLLET)
                        break
                except:
                    print("未知错误")
                    self.epollHandle.modify(sockHandle, select.EPOLLHUP | select.EPOLLET)
                    break
                num += 1
            print("数据总长度", totalLen)
            return strings
    

    为啥上面的代码 一旦我数据超过 1M,就会数据接收不全?然后该 socket 立马就会再去获取数据,导致数据再不同的两个 socket 的 recv 中。下面是获取的数据的过程,第 81 次读取数据,然后,又开始第 1 次读取数据了!!!

    第 75 次读取数据
    2896
    第 76 次读取数据
    4344
    第 77 次读取数据
    7240
    第 78 次读取数据
    第 1 次获取到空数据,继续尝试中.......
    第 79 次读取数据
    第 2 次获取到空数据,继续尝试中.......
    第 80 次读取数据
    第 3 次获取到空数据,继续尝试中.......
    第 81 次读取数据
    数据总长度 755856
    帧为:204
    Unknown opcode %#x.12
    解析数据帧暂时不用的状态
    第 1 次读取数据
    10240
    第 2 次读取数据
    10240
    第 3 次读取数据
    10240
    第 4 次读取数据
    10240
    第 5 次读取数据
    
    第 1 条附言  ·  2019-05-24 11:09:32 +08:00
    也不是固定 1M 吧,就是数据量稍微大点
    4 条回复    2019-05-24 14:27:02 +08:00
    pmispig
        1
    pmispig  
       2019-05-24 11:15:37 +08:00
    81 次读取数据,然后,又开始第 1 次读取数据了。。。我感觉你这个明显是第 2 个请求进来了。和第一个请求 81 次没有关联
    moxiaowei
        2
    moxiaowei  
    OP
       2019-05-24 13:44:07 +08:00
    @pmispig 我只发送了一个请求,是一张 1.8M 的图片,不可能有第二个请求进来
    neighbads
        3
    neighbads  
       2019-05-24 14:19:53 +08:00
    recv(1024, socket.MSG_WAITALL)
    moxiaowei
        4
    moxiaowei  
    OP
       2019-05-24 14:27:02 +08:00
    @neighbads 我的 socket 都是非阻塞模式的,貌似不能与 MSG_WAITALL 这个参数共用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5724 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 08:53 · PVG 16:53 · LAX 00:53 · JFK 03:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.