【问题标题】:Python TCP socket.recv() returns with nothing as soon as connection is made一旦建立连接,Python TCP socket.recv() 就会返回任何内容
【发布时间】:2014-01-26 03:21:12
【问题描述】:

我正在尝试实现最基本的python TCP 服务器。 Windows 8,Python 2.7,防火墙已关闭。代码来自这里:https://wiki.python.org/moin/TcpCommunication

如果我通过 python repl 执行客户端操作 (socket(...), connect(...), send(...)),一切正常,即服务器在调用 recv 时正确阻塞。

但是,如果我通过 python 脚本运行完全相同的代码(无论是否在 Windows 命令行中显式调用 python.exe),recv 会立即返回而没有数据。我在其他地方读到这意味着它是一个无效的套接字,但我不确定这意味着什么或如何检查它。我正在使用accept() 返回的套接字,而不是用于启动连接的套接字。

我试图阻止recv,这样我就可以利用超时(我不想使用选择模块,顺便说一句,它也会立即返回)并在尝试recv之间处理一些键盘内容,即用户按'q'退出。

在各种实验中,我已经证明,一旦发生这种情况,如果我将 recv 放入一个循环中,它总是会立即返回(select.select(...) 也是如此),因此客户端不会发送单个“坏”最初的数据包。如果客户端碰巧发送了一些东西,那么recv 会返回该数据,但是当它处于紧密循环中时,它肯定不会阻塞等待数据。

这是预期的行为吗?

服务器代码:

import sys
import socket


TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 20  # Normally 1024, but we want fast response

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)

conn, addr = s.accept()
print 'Connection address:', addr
while 1:
    data = conn.recv(BUFFER_SIZE) # This returns immediately with no data, when client connection is run from script and doesn't send() anything, just connects.
    if not data:
        print "broken"
        break
    print "received data:", data
    conn.send(data)  # echo

conn.close()
sys.exit()

客户端代码:

import sys
import socket

TCP_IP = '192.168.1.10'
TCP_PORT = 5005
BUFFER_SIZE = 1024
MESSAGE = "Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
# Commenting out the following to prove the recv() call on the other
#end returns with nothing instead of blocking indefinitely.  If I
#type the rest of this at the REPL the server behaves correctly,
#ie, the recv call blocks forever until socket.send("bla") from client.

#s.send(MESSAGE) data = s.recv(BUFFER_SIZE)
#s.close()
#print "received data:", data
sys.exit()

【问题讨论】:

    标签: python sockets tcp client


    【解决方案1】:

    是的,这是预期行为。

    客户端不发送任何内容。并在连接到服务器后立即退出;导致断线。

    socket.recv 如果对端执行了关闭(断开连接),则返回一个空字符串。

    虽然在 REPL 中,套接字不会关闭,直到您发出 sys.exit() 或退出交互式 shell。

    【讨论】:

    • 谢谢。我通过 a) 在客户端脚本上执行 while True: pass 循环来验证这一点,服务器 recv 被阻塞,然后 b) 从 python repl 手动逐行连接,服务器端 recv 畅通并通过 no当我从客户端 python repl 执行 s.close() 时的数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-15
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多