【发布时间】: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()
【问题讨论】: