繁体   English   中英

处理python套接字中的超时错误

[英]Handling a timeout error in python sockets

我试图找出如何使用try和除了处理套接字超时。

from socket import *

def main():
    client_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.Timeouterror:
            #more code

我添加套接字模块的方法是导入所有内容,但是如何处理文档中的异常,它说你可以使用socket.timeouterror,但这对我不起作用。 另外,如果我import socket ,我将如何编写try异常块? 有人也可以解释进口的差异。

from foo import * 

foo所有名称添加到当前模块中,而不使用前导下划线(或仅在模块__all__属性中定义的名称)。

在上面带有from socket import *代码中,您只想捕获timeout因为您已将timeout拉入当前命名空间。

from socket import *拉入socket内部的所有内容,但不添加socket本身。

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

很多人认为import *有问题,并试图避免它。 这是因为以这种方式导入的2个或更多模块中的公共变量名称将相互破坏。

例如,考虑以下三个python文件:

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

如果你运行yourcode.py你只会看到输出“这是b的foo函数”。

出于这个原因,我建议导入模块并使用它或从模块导入特定名称:

例如,您的代码看起来像显式导入:

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

只需要更多的打字,但一切都是明确的,对于读者来说,一切都来自于它。

我有足够的成功只是catchig socket.timeoutsocket.error ; 虽然可以出于很多原因引发socket.error。 小心。

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)

当您from socket import * python正在将socket模块加载到当前名称空间。 因此,您可以使用模块的成员,就像它们在您当前的python模块中定义一样。

import socket ,模块将加载到单独的命名空间中。 当您访问其成员时,您应该在它们前面加上模块名称。 例如,如果要引用socket类,则需要编写client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

至于超时的问题 - 你需要做的就是更改except socket.Timeouterror: to except timeout: ,因为在socket模块中定义了timeout类,并且你已将其所有成员导入到命名空间。

这是我在我的一个项目中使用的解决方案。

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
    }

测试

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM