Toberto
Toberto

Reputation: 139

Python Network Socket-Client freezes sporadically

I want to send some small test-data in JSON through a local network socket to a C# Server. It must be close to realtime (max. 5ms per loop). The Server is working fine and handles the incoming data without problems.

My Problem is: The Python client-side does his loops very well. But after a few loops (sometimes 100 loops, sometimes 20.000 loops, sometimes 100.000 loops) it freezes!

Then it whiles between ~ 30 - 120 seconds and then it goes on with the loops (application is completely blocked, even ALT+F4 or Taskmanager will not close the application while it is blocked).

It seems, that the local Network freezes my Socket and there is an I/O - blocking operation and the whole python-client waits for this I/O-blocking operation until it is finished and then it goes on.

If you check the Output, there is 4x the same loop-time (1.0001659393310547). What does this mean? Maybe is the while True: too fast for Network Socket ?!

I'm confused. Do you have any idea?

Python Client:

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

Output:

# 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...

Upvotes: 0

Views: 394

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 148965

Closing a socket immediately after a send yields unspecified behaviour. The data may have be sent or not because the send call returns as soon as the data has been queued and race conditions could cause the close to destroy the socket before the data has been sent.

You have 2 options to reliably close a socket:

  • use the SO_LINGER option before closing

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

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

Upvotes: 1

Related Questions