Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 只有在成功传输后,才能关闭Greenlet中的TCP套接字_Python_Sockets_Asynchronous_Gevent - Fatal编程技术网

Python 只有在成功传输后,才能关闭Greenlet中的TCP套接字

Python 只有在成功传输后,才能关闭Greenlet中的TCP套接字,python,sockets,asynchronous,gevent,Python,Sockets,Asynchronous,Gevent,只有在成功传输所有数据后,我才尝试关闭TCP套接字: from gevent import monkey; monkey.patch_all() import gevent import socket host = "127.0.0.1" port = 8888 line_term = "\r\n" login_str = ["Action: Login", "ActionID: 1", "Username: ami",

只有在成功传输所有数据后,我才尝试关闭TCP套接字:

from gevent import monkey; monkey.patch_all()
import gevent
import socket

host = "127.0.0.1"
port = 8888

line_term = "\r\n"

login_str = ["Action: Login",
             "ActionID: 1",
             "Username: ami",
             "Secret: password",
             ]

def login(login_str):
    conn = socket.create_connection([host, port])

    for i in login_str:
        conn.sendall(i + line_term)

    conn.send(line_term)
    # Everything works, as soon as I uncomment this line below :/
    # gevent.sleep(1)
    conn.close()

g1 = gevent.spawn(login, login_str)
g1.join(timeout=2)
看起来,这个套接字关闭得太快了,因为我总是在另一端只收到我的
login\u str
的前两行。如果我取消注释
gevent.sleep(1)
,一切正常。但我怀疑这种情况是否会发生,如果我尝试发送1000行或使用拍打连接,可能需要的超时时间为2秒。这是不可预测的,也是异步的不可取的副作用。编程,就我看来,所以我很确定一定有一个简单的解决办法,我就是找不到

编辑

为了完整起见,我还添加了echo服务器部分:

from gevent.server import StreamServer

def connection_handler(socket, address):
    for l in socket.makefile('r'):
        print str(len(l)) + ' : ' + l
        socket.sendall(l)


if __name__ == '__main__':
    server = StreamServer(('0.0.0.0', 8888), connection_handler)
    server.serve_forever()

在您的服务器代码中,您正在回显您读取的每一行(
socket.sendall(l)
)。但是,在客户机代码中,一旦发送了所有数据,服务器就没有机会发回数据,即关闭连接。如果您注释掉socket.sendall(l),您将看到确实收到了所有四行

如果确实需要发回数据,可以修改客户端代码以等待服务器完成所有数据的发送:

def login(login_str):
    conn = socket.create_connection([host, port])

    for i in login_str:
        conn.sendall(i + line_term)

    conn.send(line_term)

    # Wait until the other end has finished sending data

    while conn.recv(1024):
      pass

    # Everything works, as soon as I uncomment this line below :/
    # gevent.sleep(1)
    conn.close()

当您在最后一行加入主线程时
g1.join(timeout=2)
,您只需等待2秒钟。那可能是你的问题。尝试删除超时,看看是否有帮助。不幸的是,更改为
g1.join()
没有任何效果。在另一端使用
nc-l-p8888
运行您的精确代码对我来说很好。您的服务器代码可能有问题。此程序的同步版本对我也很有效,这就是重点:)请查看更新的问题。