Son*_*oth 2 python sockets client tcp
我正在尝试实现最基本的python TCP服务器.Windows 8,Python 2.7,防火墙已关闭.代码来自这里:https://wiki.python.org/moin/TcpCommunication
如果我socket(...), connect(...), send(...)通过python repl 做客户端stuff(),一切正常,即服务器在调用时正确阻塞recv.
但是,如果我通过python脚本运行完全相同的代码(无论是否在Windows命令行显式调用python.exe),recv立即返回没有数据.我在其他地方读到SO这意味着它是一个无效的套接字,但我不确定这意味着什么或如何检查它.我使用的是accept()不是用于启动连接的套接字返回的套接字.
我试图阻止,recv所以我可以利用超时(我不想使用选择模块,BTW也立即返回)并在尝试之间处理一些键盘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()
Run Code Online (Sandbox Code Playgroud)
客户代码:
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()
Run Code Online (Sandbox Code Playgroud)
是的,这是预期的行为.
客户端不发送任何内容.它一连接到服务器就退出; 断开连接.
socket.recv 如果对等方执行shutdown(disconnect),则返回空字符串.
而在REPL中,套接字在您发出sys.exit()或退出交互式shell 之前不会关闭.