Dies ist in der API für Interactive Brokers als „connection.py“ codiert. Wenn es ausgeführt wird, gibt es den Fehler „Ein Vorgang wurde an etwas versucht, das kein Socket war“ zurück, bei „buf = self.socket.recv(4096)“. Ich habe versucht, den an recv übergebenen Wert auf 7497 zu ändern, damit er mit dem Socket-Port übereinstimmt, aber ich bekomme dieselbe Meldung. Ich denke, es könnte sich um einen Formatierungsfehler handeln, aber ich bin zu neu in Python, um das sicher zu wissen.
logger = logging.getLogger(__name__)
class Connection:
def __init__(self, host, port):
self.host = host
self.port = port
self.socket = None
self.wrapper = None
self.lock = threading.Lock()
def connect(self):
try:
self.socket = socket.socket()
#TODO: list the exceptions you want to catch
except socket.error:
if self.wrapper:
self.wrapper.error(NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg())
try:
self.socket.connect((self.host, self.port))
except socket.error:
if self.wrapper:
self.wrapper.error(NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg())
self.socket.settimeout(1) #non-blocking
def disconnect(self):
self.lock.acquire()
try:
if self.socket is not None:
logger.debug("disconnecting")
self.socket.close()
self.socket = None
logger.debug("disconnected")
if self.wrapper:
self.wrapper.connectionClosed()
finally:
self.lock.release()
def isConnected(self):
return self.socket is not None
def sendMsg(self, msg):
logger.debug("acquiring lock")
self.lock.acquire()
logger.debug("acquired lock")
if not self.isConnected():
logger.debug("sendMsg attempted while not connected, releasing lock")
self.lock.release()
return 0
try:
nSent = self.socket.send(msg)
except socket.error:
logger.debug("exception from sendMsg %s", sys.exc_info())
raise
finally:
logger.debug("releasing lock")
self.lock.release()
logger.debug("release lock")
logger.debug("sendMsg: sent: %d", nSent)
return nSent
def _recvMsg(self):
if not self.isConnected():
logger.debug("recvMsg attempted while not connected, releasing lock")
return b""
try:
buf = self.recvAllMsg()
# receiving 0 bytes outside a timeout means the connection is either
# closed or broken
if len(buf) == 0:
logger.debug("socket either closed or broken, disconnecting")
self.disconnect()
except socket.timeout:
logger.debug("socket timeout from recvMsg %s", sys.exc_info())
buf = b""
else:
pass
return buf
def recvAllMsg(self):
cont = True
allbuf = b""
while cont and self.socket is not None:
buf = self.socket.recv(4096)
allbuf += buf
logger.debug("len %d raw:%s|", len(buf), buf)
if len(buf) < 4096:
cont = False
return allbuf
Antwort1
4096 ist die Puffergröße, nicht die Portnummer. Dieser Fehler tritt auf, weil ein Thread beendet wird, während ein anderer versucht zu schreiben (an einen nicht vorhandenen Ort). Es ist ein IB-Problem, sollte aber keine Probleme verursachen, es ist einfach nur hässlich.
Antwort2
Ein Workaround, den Sie bei IhremEClient / EWrapper-Klasse:
- Erstellen einer Socket-Shutdown-Funktion
- Verwenden Sie es, bevor Sie die Disconnect-Methode aufrufen
# create function
def _socketShutdown(self):
self.conn.lock.acquire()
try:
if self.conn.socket is not None:
self.conn.socket.shutdown(socket.SHUT_WR)
finally:
self.conn.lock.release()
# use it
self._socketShutdown()
time.sleep(1)
self.disconnect()