我有套接字将Prologixx GPIB查询为ETH0。我得到了 friend 执行此操作的代码。在Win 10中,套接字随机获得超时,有时计算机似乎关闭了连接。我想认识到,套接字有问题,无法再次启动它。

有两条消息:



这只会产生无效的结果,我正在检查结果是否合理。也只是暂时的



这是永久的。该程序像以前一样运行,只是死了没有得到新的结果。测试新结果很困难,因为它们是温度,而且我会稳定一段时间。

import socket
from numpy import nan
from time import sleep
class PrologixGPIBEthernet:
    PORT = 1234

    def __init__(self, host, timeout=1):
        self.host = host
        self.timeout = timeout

        self.socket = socket.socket(socket.AF_INET,
                                    socket.SOCK_STREAM,
                                    socket.IPPROTO_TCP)
        self.socket.settimeout(self.timeout)

    def connect(self):
        self.socket.connect((self.host, self.PORT))

        self._setup()

    def close(self):
        self.socket.close()

    def select(self, addr):
        self._send('++addr %i' % int(addr))

    def write(self, cmd):
        self._send(cmd)

    def read(self, num_bytes=1024):
        self._send('++read eoi')
        return self._recv(num_bytes)

    def query(self, cmd, buffer_size=1024*1024):
        self.write(cmd)
        return self.read(buffer_size)

    def _send(self, value):
        encoded_value = ('%s\n' % value).encode('ascii')
        try:
            s = self.socket.send(encoded_value)
        except Exception as e:
            print('_send', e)

    def _recv(self, byte_num):
        try:
            value = self.socket.recv(byte_num).decode('ascii')
        except Exception as e:
            print (',_recv', e)
            value = 'ERROR'
        return value

    def _setup(self):
        # set device to CONTROLLER mode
        self._send('++mode 1')

        # disable read after write
        self._send('++auto 1')

        # set GPIB timeout
#        self._send('++read_tmo_ms %i' % int(self.timeout*1e3))

        # do not require CR or LF appended to GPIB data
#        self._send('++eos 3')

最佳答案

我不确定错误消息,但这听起来与我的经验相似。

我将prologix设备称为“解释器”,因为它无法与SCPI无缝配合使用。

例如,对于普通的SCPI仪器,我可以要求设备进行测量,然后可以要求读取该测量值,完成后它会给我一个响应。只要超时时间长,它就会挂起,直到缓冲区被填满,然后返回结果。 (注意:这不是您应该采取的方式。使用轮询或中断是实现设备查询的好方法。)

prologix设备可能会与时间混淆。如果我尝试通过发送读取测量值的命令来复制SCPI的工作方式(如上所述),但是这次进行该测量并将其放入缓冲区需要5秒钟。在5秒钟过去之前,我问prologix结果是什么,它将尝试查找结果,但是缓冲区为空,因此没有任何返回值。 5秒钟后,缓冲区被填满,但是prologix不知道这一点,并停留在此状态。这是您获得套接字超时的地方。

解决此问题的正确方法是使用prologix中的轮询功能在缓冲区有结果时进行计算。但这不是我要做的事情。

技巧1)确保有足够大的延迟,但是您并不总是知道需要多长时间,并且会增加脚本延迟。

哈克2)故意强制您的脚本超时并重试。这就是我已经实现的。我知道这很丑陋,但是当我试图找出问题所在时,这是一个快速的技巧。

def read_timeout_poll(self, repeat):
    # start_time = time.time() # Used if you want to see how long it takes
    mesg = ""
    for _ in range(repeat):
        try:
            sendData = "++read\n"
            self.prolSock.send(sendData.encode())
            mesg = self.prolSock.recv(self.BUFSIZ)
            break
        except socket.timeout:
            time.sleep(1)
        except socket.error as e:
            return "Python Error sending data: " + str(e)
            break
    # print(f"read poll operation took {:.0f} seconds".format(time.time() - start_time)) # This is a guide to see how long it takes to get a result in the buffer
    return mesg

10-06 04:10