建立连接后,Python TCP socket.recv()一无所获 [英] Python TCP socket.recv() returns with nothing as soon as connection is made

查看:96
本文介绍了建立连接后,Python TCP socket.recv()一无所获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement the most basic python TCP server. Windows 8, Python 2.7, firewall is turned off. Code is from here: https://wiki.python.org/moin/TcpCommunication

如果我通过python repl做客户端的事情( socket(...),connect(...),send(...)),则一切正常,即服务器正常调用 recv 时阻止.

If I do the client stuff (socket(...), connect(...), send(...)) via python repl, things work fine, ie the server correctly blocks when calling recv.

但是,如果我通过python脚本运行完全相同的代码(在Windows命令行中有显式调用python.exe或没有显式调用python.exe的情况下), recv 将立即返回且不包含任何数据.我在其他地方读过,所以这意味着它是无效的套接字,但是我不确定这是什么意思或如何检查它.我使用的是 accept()返回的套接字,而不是用于启动连接的套接字.

However if I run the exact same code via python script (both with and without explicitly calling python.exe at windows command line), the recv returns immediately with no data. I read elsewhere on SO this means it's an invalid socket, but I'm not sure what that means or how to check for it. I'm using the socket returned by accept() not the one used to initiate the connection.

我正在尝试阻止 recv ,所以我可以利用超时(我不想使用select模块,而且BTW也会立即返回)并在两次尝试之间处理一些键盘内容到 recv ,即用户按"q"退出.

I'm trying to block on recv so I can take advantage of the timeout (I don't want to use select module, which BTW also returns immediately) and process some keyboard stuff between attempts to recv, ie user presses 'q' to quit.

在各种实验中,我已经证明,一旦发生这种情况, recv 总是会立即返回( select.select(...)也会立即返回)在一个循环中,所以这不像客户端最初发送单个坏"数据包.如果客户端碰巧发送了某些内容,则 recv 会返回该数据,但是当处于紧密循环中时,它肯定不会阻止等待数据.

In various experiments I've shown that once this occurs, recv will always return immediately (as will select.select(...)) if I put it in a loop, so it's not like the client is sending a single "bad" packet initially. If the client happens to have sent something, then the recv returns with that data, but it certainly doesn't block waiting for data when put in a tight loop.

这是预期的行为吗?

服务器代码:

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()

推荐答案

是的,这是预期的行为.

Yes, this is expected behavior.

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

The client does not send anything. And it exit as soon as it connect to the server; cause disconnection.

socket.recv 返回空如果对等方执行了关机(断开连接)操作,则为字符串.

socket.recv returns an empty string if the peer performed shutdown (disconnect).

在REPL中,直到您发出 sys.exit()或退出交互式外壳程序后,套接字才会关闭.

While, in the REPL, the socket is not closed until you issue sys.exit() or you quit the interactive shell.

这篇关于建立连接后,Python TCP socket.recv()一无所获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆