Python网络套接字客户端偶尔会冻结

时间:2018-07-11 08:49:20

标签: python sockets networking io

我想通过本地网络套接字将JSON中的一些小测试数据发送到C#服务器。它必须接近实时(每个循环最多5毫秒)。服务器工作正常,可以毫无问题地处理传入数据。

我的问题是:Python客户端的循环很好。但是经过几个循环(有时100个循环,有时20.000个循环,有时100.000个循环),它冻结了!

然后它在约30-120秒之间运行,然后继续循环(应用程序被完全阻止,即使ALT + F4或Taskmanager也将在被阻止时关闭应用程序)。

看来,本地网络冻结了我的套接字,并且有一个I / O阻止操作,整个python客户端都在等待该I / O阻止操作,直到操作完成,然后继续进行。

如果您检查输出,则有4倍的相同循环时间( 1.0001659393310547 )。这是什么意思?也许 while True:对于网络套接字来说太快了吗?!

我很困惑。你有什么主意吗?

Python客户端:

import json
import socket
import time

TCP_IP = '127.0.0.1'
TCP_PORT = 5005
ITERATOR = 0


def getData():
    return json.load(open('data.json'))


while True:
    ITERATOR += 1
    now = time.time()
    _data = getData()
    _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    _socket.connect((TCP_IP, TCP_PORT))
    _socket.send(bytearray(str(_data).encode()))
    _socket.close()
    print('# %i | Loop Time (ms) : %s' % (ITERATOR, ((time.time() - now)*1000)))

输出:

# 1023 | Loop Time (ms) : 1.5003681182861328
# 1024 | Loop Time (ms) : 1.0001659393310547
# 1025 | Loop Time (ms) : 1.0001659393310547
# 1026 | Loop Time (ms) : 1.0001659393310547
# 1027 | Loop Time (ms) : 1.0001659393310547
# 1028 | Loop Time (ms) : 1.5001296997070312
...

AND THEN IT FREEZES !!!! It freezes for some seconds/minutes and the goes on...

1 个答案:

答案 0 :(得分:1)

在发送后立即关闭套接字会产生未指定的行为。数据是否已发送,因为一旦数据已排队,send调用就会立即返回,而竞争条件可能会导致关闭在数据发送之前关闭套接字。

您有2个选项可以可靠地关闭套接字:

  • 在关闭前使用SO_LINGER选项

    _socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                       struct.pack('ii', 1, 0))
    
  • 使用graceful shutdown

    _socket.shutdown(socket.SHUT_WR) # shutdown the socket
    _socket.read() # wait the close from peer
    _socket.close()