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-21 09:28:04 +08:00 · 1801 次点击
    这是一个创建于 2014 天前的主题,其中的信息可能已经有所发展或是发生改变。

    socket 接收数据代码如下: 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
    

    我一直循环接收数据,理论上会接收到 3 次及 3 次以上空数据就会退出接收数据,但是,实际发现只要数据量有点大,就会导致循环退出,然后会重新再接收数据。下面是数据打印的结果 10240 第 56 次读取数据 10240 第 57 次读取数据 8656 第 58 次读取数据 第 1 次获取到空数据,继续尝试中....... 第 59 次读取数据 第 2 次获取到空数据,继续尝试中....... 第 60 次读取数据 第 3 次获取到空数据,继续尝试中....... 第 61 次读取数据 数据总长度 582096 帧为:127 Unknown opcode %#x.15 解析数据帧暂时不用的状态 第 1 次读取数据--------------------------------->这儿明显重新开始接收数据了!!! 10240 第 2 次读取数据 10240

    求解各位大神

    4 条回复    2019-05-25 18:22:40 +08:00
    guyeu
        1
    guyeu  
       2019-05-21 10:52:30 +08:00
    这排版,辣眼睛。
    diveIntoWork
        2
    diveIntoWork  
       2019-05-21 10:57:42 +08:00
    建议好好排下版再问
    BingoXuan
        3
    BingoXuan  
       2019-05-21 21:34:27 +08:00 via Android
    所以源码都没贴全是让大家脑补帮你 debug 吗?

    请问你 epollHandle.modify 有没有把 socket 给 close 掉?没有的话,对端会一直发空字符串过来,告诉你关闭 socket 的。但这一部分没有贴出来,所以我怀疑你 modify 方法没有关闭 socket,导致对端一直发送空字符串,让你一直以为有数据接受。

    c 的 epoll 我记得也是发送空字符串告诉你 socket 关闭的,python 和 c 在系统 api 上差异不大
    moxiaowei
        4
    moxiaowei  
    OP
       2019-05-25 18:22:40 +08:00
    @BingoXuan 这块我处理了的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1039 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:16 · PVG 07:16 · LAX 15:16 · JFK 18:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.