Handling a timeout error in python sockets

前端 未结 4 2099
醉话见心
醉话见心 2020-12-14 15:38

I am trying to figure out how to use the try and except to handle a socket timeout.

from socket import *

def main():
    client_socket = socket(AF_INET,SOC         


        
相关标签:
4条回答
  • 2020-12-14 16:20

    I had enough success just catchig socket.timeout and socket.error; although socket.error can be raised for lots of reasons. Be careful.

    import socket
    import logging
    
    hostname='google.com'
    port=443
    
    try:
        sock = socket.create_connection((hostname, port), timeout=3)
    
    except socket.timeout as err:
        logging.error(err)
    
    except socket.error as err:
        logging.error(err)
    
    0 讨论(0)
  • 2020-12-14 16:21

    When you do from socket import * python is loading a socket module to the current namespace. Thus you can use module's members as if they are defined within your current python module.

    When you do import socket, a module is loaded in a separate namespace. When you are accessing its members, you should prefix them with a module name. For example, if you want to refer to a socket class, you will need to write client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM).

    As for the problem with timeout - all you need to do is to change except socket.Timeouterror: to except timeout:, since timeout class is defined inside socket module and you have imported all its members to your namespace.

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

    Here is a solution I use in one of my project.

    network_utils.telnet

    import socket
    from timeit import default_timer as timer
    
    def telnet(hostname, port=23, timeout=1):
        start = timer()
        connection = socket.socket()
        connection.settimeout(timeout)
        try:
            connection.connect((hostname, port))
            end = timer()
            delta = end - start
        except (socket.timeout, socket.gaierror) as error:
            logger.debug('telnet error: ', error)
            delta = None
        finally:
            connection.close()
    
        return {
            hostname: delta
        }
    

    Tests

    def test_telnet_is_null_when_host_unreachable(self):
        hostname = 'unreachable'
    
        response = network_utils.telnet(hostname)
    
        self.assertDictEqual(response, {'unreachable': None})
    
    def test_telnet_give_time_when_reachable(self):
        hostname = '127.0.0.1'
    
        response = network_utils.telnet(hostname, port=22)
    
        self.assertGreater(response[hostname], 0)
    
    0 讨论(0)
  • 2020-12-14 16:27
    from foo import * 
    

    adds all the names without leading underscores (or only the names defined in the modules __all__ attribute) in foo into your current module.

    In the above code with from socket import * you just want to catch timeout as you've pulled timeout into your current namespace.

    from socket import * pulls in the definitions of everything inside of socket but doesn't add socket itself.

    try:
        # socketstuff
    except timeout:
        print 'caught a timeout'
    

    Many people consider import * problematic and try to avoid it. This is because common variable names in 2 or more modules that are imported in this way will clobber one another.

    For example, consider the following three python files:

    # a.py
    def foo():
        print "this is a's foo function"
    
    # b.py
    def foo():
        print "this is b's foo function"
    
    # yourcode.py
    from a import *
    from b import *
    foo()
    

    If you run yourcode.py you'll see just the output "this is b's foo function".

    For this reason I'd suggest either importing the module and using it or importing specific names from the module:

    For example, your code would look like this with explicit imports:

    import socket
    from socket import AF_INET, SOCK_DGRAM
    
    def main():
        client_socket = socket.socket(AF_INET, SOCK_DGRAM)
        client_socket.settimeout(1)
        server_host = 'localhost'
        server_port = 1234
        while(True):
            client_socket.sendto('Message', (server_host, server_port))
            try:
                reply, server_address_info = client_socket.recvfrom(1024)
                print reply
            except socket.timeout:
                #more code
    

    Just a tiny bit more typing but everything's explicit and it's pretty obvious to the reader where everything comes from.

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