Python - Asyncore (client) socket - Can not determaine connection status

时光毁灭记忆、已成空白 提交于 2019-12-10 11:54:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!