How to use python socket.settimeout() properly

前端 未结 3 1049
自闭症患者
自闭症患者 2020-12-31 13:33

As far as I know, when you call socket.settimeout(value) and you set a float value greater than 0.0, that socket will raise a scocket.timeout when a call to, fo

相关标签:
3条回答
  • 2020-12-31 14:13

    See my server script, you will get the idea to use it properly.

    import socket
    import sys
    fragments = []
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(("192.168.1.4",9001))
    s.listen(5)
    while True:
        c,a = s.accept()
        c.settimeout(10.0)
        print "Someone came in Server from %s and port %s" %(a[0],a[1])
        c.send("Welcome to system")
        while True:
            chunk = c.recv(2048)
            if not chunk.strip():
                break
            else:
                fragments.append(chunk)
                continue
        combiner = "".join(fragments)
        print combiner
        shutdown = str(raw_input("Wanna Quit(Y/y) or (N/n): "))
        if shutdown == 'Y' or shutdown == 'y':
            c.close()
            sys.exit()
        else:
            continue
    

    This script is just to give you an idea about the socket.settimeout().

    0 讨论(0)
  • 2020-12-31 14:14

    The timeout applies to each call to recv().

    A) simply use your existing timeout and call recv(to_receive) - I.e. Try to receive all the data in one recv call - in fact I don't see why you shouldn't use this as the default way it works

    B) No nothing bad could happen, but any other code which uses that socket needs to be aware of handling timeout.

    On your existing code, shouldn't the recv() call be recv(max(4096,to_receive-received)) - that way you won't unintentionally consume any data which follows after the to_receive bytes.

    0 讨论(0)
  • 2020-12-31 14:16

    Timeout applies to a single call to socket read/write operation. So next call it will be 20 seconds again.

    A) To have a timeout shared by several consequential calls, you'll have to track it manually. Something along these lines:

    deadline = time.time() + 20.0
    while not data_received:
        if time.time() >= deadline:
            raise Exception() # ...
        socket.settimeout(deadline - time.time())
        socket.read() # ...
    

    B) Any code that's using a socket with a timeout and isn't ready to handle socket.timeout exception will likely fail. It is more reliable to remember the socket's timeout value before you start your operation, and restore it when you are done:

    def my_socket_function(socket, ...):
        # some initialization and stuff
        old_timeout = socket.gettimeout() # Save
        # do your stuff with socket
        socket.settimeout(old_timeout) # Restore
        # etc
    

    This way, your function will not affect the functioning of the code that's calling it, no matter what either of them do with the socket's timeout.

    0 讨论(0)
提交回复
热议问题