问题
For some reason, self.connected
of the asyncore.dispatcher
class doesn't consider my socket to be connected on the client side. The server side sees the socket as connected and treats it as such, but the client doesn't know if it's connected or not and handle_connect
doesn't "proc", so i can't use a overridden version of it to check if the socket is connected either.
Any thoughts on this code why it ain't working:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import asyncore
from threading import *
from socket import *
from time import sleep
from os import _exit
from logger import *
from config import *
class logDispatcher(asyncore.dispatcher):
def __init__(self, config=None):
self.inbuffer = ''
self.buffer = ''
self.lockedbuffer = False
self.is_writable = False
asyncore.dispatcher.__init__(self)
#Thread.__init__(self)
self.create_socket(AF_INET, SOCK_STREAM)
#self.is_writable = True
#self.start()
def compare(self, obj, otherobj):
return (str(obj).lower() == str(otherobj).lower()[:len(str(obj))])
def _in(self, obj, otherobj):
return (str(obj).lower() in str(otherobj).lower())
def parse(self):
if self.inbuffer[-2:] != '\r\n':
return False
self.lockedbuffer = True
self.inbuffer = ''
self.lockedbuffer = False
def readable(self):
return True
def handle_connect(self):
log('Connected to ' + str(server), 'SOCK_CORE')
def handle_close(self):
self.close()
def handle_read(self):
data = self.recv(8192)
while self.lockedbuffer:
sleep(0.01)
self.inbuffer += data
def writable(self):
return (len(self.buffer) > 0)
def handle_write(self):
while self.is_writable:
sent = self.send(self.buffer)
sleep(1)
self.buffer = self.buffer[sent:]
if len(self.buffer) <= 0:
self.is_writable = False
sleep(0.01)
def _send(self, what):
self.buffer += what + '\r\n'
self.is_writable = True
def handle_error(self):
log('Error, closing socket!', 'SOCK_CORE')
self.close()
def run(self):
log('Log socket engine initating', 'SOCK_CORE')
self.connect((server, server_port))
print self.connected
sleep(3)
print self.connected
class start(Thread):
def __init__(self):
Thread.__init__(self)
self.start()
def run(self):
asyncore.loop(0.1)
start()
logDisp = logDispatcher()
logDisp.run()
回答1:
def handle_connect_event(self):
self.is_connected = True
Adding that to your dispatcher will give you a way to check if the socket is connected or not, thanks to some stack trace (python -m trace -t script.py
) in Python I managed to figure out that the asyncore
class automaticly created that function for whatever reason, and it was called continiously as long as the socket was connected or in a connected state.
After that, i also replaced the threaded asyncore.loop() and replaced it with a "static" placement locking your main thread, one of these two combinations (or both) solved the issue for now.. the logic isn't the same as in my problem which i don't like but i assume that i'll be needing to create my own dispach_event just like if i were to do a OpenGL GUI class where i would call dispatch_event() manually every loop some how in the thread to "keep things alive".. it's just a thought..
Anyway, here's a working example:
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import asyncore, socket
from threading import *
from time import sleep
from os import _exit
from logger import *
from config import *
def _map():
return {}
def _array():
return []
class logDispatcher(Thread, asyncore.dispatcher):
def __init__(self, config=None):
self.inbuffer = ''
self.buffer = ''
self.lockedbuffer = False
self.is_writable = False
self.is_connected = False
self.exit = False
self.initated = False
asyncore.dispatcher.__init__(self)
Thread.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.connect((server, server_port))
except:
log('Could not connect to ' + server, 'LOG_SOCK')
return None
self.start()
def handle_connect_event(self):
self.is_connected = True
def handle_connect(self):
self.is_connected = True
log('Connected to ' + str(server), 'LOG_SOCK')
def handle_close(self):
self.is_connected = False
self.close()
def handle_read(self):
data = self.recv(8192)
while self.lockedbuffer:
sleep(0.01)
self.inbuffer += data
def handle_write(self):
while self.is_writable:
sent = self.send(self.buffer)
sleep(1)
self.buffer = self.buffer[sent:]
if len(self.buffer) <= 0:
self.is_writable = False
sleep(0.01)
def _send(self, what):
self.buffer += what + '\r\n'
self.is_writable = True
def run(self):
sleep(1)
log('Log engine initating (hooking on to main)', 'LOG_CORE')
main = None
for t in enumerate():
if t.getName() == 'MainThread':
main = t
log('Log engine attached to main', 'LOG_CORE')
while (main and main.isAlive()) and (self.connected or self.is_connected):
print 'WHAM', self.connected, self.is_connected
sleep(1)
while 1:
logDisp = logDispatcher()
asyncore.loop(0.1)
log('Logserver disconnected, trying to reconnect!', 'CORE')
sleep(10)
来源:https://stackoverflow.com/questions/15753901/python-asyncore-client-socket-can-not-determaine-connection-status