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
among
V2EX  ›  Python

一个 Python socket 中的超时错误(有 wireshark 截图)

  •  1
     
  •   among · 2019-10-29 22:35:55 +08:00 · 2672 次点击
    这是一个创建于 1612 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在写一个 python 的模拟请求客户端,原先有个其他人提供的 java 程序。这个 java 发送正常,可以成功收到响应。 使用 python socket 进行模拟,每次都是超时,接收不到任何数据,使用了多种方式仍然不行,使用 charles 做 端口转发,java 的也会失败,最后使用 wireshark 抓包。

    截图

    19.53 是客户端,6.60 是服务器端。

    图中,前面一个是 java 正常发送接收的例子,比较奇怪的是发出报文体( No193 ),接着 194 就发出了 “FIN ACK”。

    从 No 1284 开始的是 python 请求,在发出报文体( No 1287 )后,服务器直接反馈了一个 ACK,并没有发出响应报文,后续进入超时等待的时间,直到 python 端发出 socket close ( No 1724 ),服务端才响应报文( No 1725 ),这个时候请求端已经关闭连接了,什么都没收到。

    代码如下:

     		try:
                self.sok.connect((ip, int(port)))
                self.sok.send(msg)
                self.sok.settimeout(int(timeout))
                rsp = self.sok.recv(1024)
                self.sok.close()
            except Exception as ex:
                print('socket_send: %s:%d ,error: %s' %
                      (ip, int(port), traceback.format_exc()))
                rsp = b''
     ........
    

    还使用了

            try:
                self.sok.connect((ip, int(port)))
                self.sok.send(msg)
                self.sok.settimeout(int(timeout))
                while True:
                    data = self.sok.recv(1024)
                    print(data)
                    if not data:
                        break
                    total_data.append(data)
    

    这几个都是一样的错误,现在很奇怪,为什么 java 的可以成功,python 的接收不到报文。 请大家帮忙看下。

    第 1 条附言  ·  2019-10-30 09:58:37 +08:00

    问题已经解决

    增加了

                self.sok.shutdown(socket.SHUT_WR)
    
    

    在发出报文之后,主动关闭写,然后就可以正常使用接受方法接收到请求了。

    谢谢,@ysc3839

    7 条回复    2019-10-30 09:55:21 +08:00
    ysc3839
        1
    ysc3839  
       2019-10-29 23:02:44 +08:00
    反编译 Java 程序看看?
    lcdtyph
        2
    lcdtyph  
       2019-10-29 23:05:26 +08:00 via iPhone
    你的 py 版本发送的内容不全,或者格式错了,导致服务端一直在等待后续内容从而超时了。

    你需要对比的是两个版本 tcp payload 的内容,从图里看,java 版发送了 174 字节,而 py 版只发送了 155 字节
    superrichman
        3
    superrichman  
       2019-10-29 23:23:07 +08:00 via iPhone
    socket 初始化参数?
    ysc3839
        4
    ysc3839  
       2019-10-29 23:39:04 +08:00
    或者试一下 send 之后调用一下 socket.shutdown(SHUT_WR) ?
    sunnyadamm
        5
    sunnyadamm  
       2019-10-29 23:40:31 +08:00 via Android
    2l 正解,你两个包大小不一致,看看你的 py 发送少了啥吧
    among
        6
    among  
    OP
       2019-10-30 09:46:46 +08:00
    @sunnyadamm
    @lcdtyph

    数据包的内容是一致的。

    ![截图]( https://imamong.github.io/media/15723578856199/15723995295101.jpg)

    响应的大小也是一样,不是发送内容的问题。
    among
        7
    among  
    OP
       2019-10-30 09:55:21 +08:00
    ```python
    self.sok.shutdown(socket.SHUT_WR)
    ``

    增加了主动关闭发送的设置,现在可以正常接收响应了,问题解决。
    谢谢,@ysc3839
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2826 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 15:23 · PVG 23:23 · LAX 08:23 · JFK 11:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.