从客户端关闭套接字,以便asyncore服务器检测到它

时间:2012-11-10 16:15:18

标签: python multithreading sockets tcp asyncore

我正在构建一个聊天服务器客户端系统。在客户端创建套接字以连接到在端口侦听的服务器。问题是当我尝试从客户端关闭套接字时,asyncore handle_close没有检测到它。

服务器代码:

clients = {}
identity={}
class MainServerSocket(asyncore.dispatcher):
def __init__(self, port):
    asyncore.dispatcher.__init__(self)
    self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
    self.bind(('',port))
    self.listen(5)
def handle_accept(self):
    newSocket, address = self.accept( )
    clients[address] = newSocket
    #try : 
        #hndl=newSocket.recv(1024)
        #print "Connected from", address,hndl
    #except : 
        #e = sys.exc_info()[1]
    print "Connected from", address
    handler=SecondaryServerSocket(newSocket)
    handler.setAddr(address)
    every = clients.values()
    for one in every:
        one.send('Server message:'+str(address)+' joined'+'\n')

class SecondaryServerSocket(asyncore.dispatcher_with_send):
def setAddr(self, addr):
    self.addr = addr

def isid(self,txt):
    pattern=re.compile('\*\$\$\$\*(.+)\*\$\$\$\*')
    match=pattern.search(txt)
    rv=0
    if match :
        self.hndl=match.group(1)
        rv=1
        if self.hndl not in identity.values():
            identity[self.addr]=self.hndl 
            every=clients.values()
            for one in every:
                one.send('Server message:'+str(self.addr)+' is known as '+self.hndl+'\n')
        else:
            clients[self.addr].send("Server message: handle in use, retry. Disconnecting.")
            self.close()
    return rv    #del clients[self.addr]    
def handle_read(self):
    receivedData = self.recv(8192)
    if receivedData:
        if not self.isid(receivedData):
        #self.addr
            every = clients.values()
            for one in every:
                one.send(receivedData)
    else: self.close( )
def handle_close(self):
    print "Disconnected from", self.getpeername( )

    one = self.getpeername( )
    del identity[one]
    del clients[one]
    every=clients.values()
    try:    
        for one in every:
            one.send('server message:'+str(self.addr)+' quit'+'\n')
    except: pass
print "server started"
MainServerSocket(21567)
asyncore.loop( ) 

客户端代码(相关位):

    class Application(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.serv_ip=StringVar()
        self.port=StringVar()
        self.handle=StringVar()
        self.serv_ip.set('127.0.0.1')
        self.port.set('21567')
        self.grid()
        self.create_widgets()
        self.lastname=""
        self.currentname=""
        self.delim=('-'*45)+'\n'
    def connect(self):
        if len(self.handle.get())>0 and not self.handle.get().isspace() :
            HOST = self.serv_ip.get()
            PORT = int(self.port.get())
            #BUFSIZE = 1024
            ADDR = (HOST, PORT)
            try:
                self.tcpCliSock = socket(AF_INET, SOCK_STREAM)
                self.tcpCliSock.connect(ADDR)
                idtext='*$$$*'+self.handle.get()+'*$$$*'
                self.tcpCliSock.send(idtext)
                self.add("sys message: CONNECTED TO "+str(HOST)+':'+str(PORT)+'\n')
                self.socket()
                self.con_button.configure(text="DISCONNECT!",command=self.disconnect)
                self.entry_field.configure(state=NORMAL)
                self.handle_entry.configure(state=DISABLED)
            except: 
                e = sys.exc_info()[1]
                self.add("sys message: ERROR CONNECTING to "+str(HOST)+':'+str(PORT)+"   "+str(e)+'\n')
                #pass
        else : self.add("sys message: Enter handle/nickname and try again."+'\n')

    def disconnect(self):
        #try : self.tcpCliSock.shutdown(2)
        #except: pass
        #self.tcpCliSock.close()
        self.tcpCliSock.send('')
        self.tcpCliSock.close()
        self.closeflag=1
        self.add("sys message: Disconnected."+'\n')
        self.con_button.configure(text="CONNECT!",command=self.connect)
        self.entry_field.configure(state=DISABLED)
        self.handle_entry.configure(state=NORMAL)
        self.closeflag=0
        #self.send_button.configure(state=DISABLED)

    def socket(self):
    def loop0():
        while 1:
            try:
                if self.closeflag==0: 
                    data = self.tcpCliSock.recv(BUFSIZE)

                    if data: self.add(data)
            except:
                e = sys.exc_info()[1]
                self.add("ERROR: "+str(e)+'  disconnecting...'+'\n')
                self.con_button.configure(text="CONNECT!",command=self.connect)
                self.entry_field.configure(state=DISABLED)
                self.handle_entry.configure(state=NORMAL)
                self.closeflag=0
                thread.exit()
                #self.disconnect()
                break
            if self.closeflag==1 :
                self.tcpCliSock.close()
                print "ping"
                thread.exit()

    thread.start_new_thread(loop0, ())

我知道这是很多代码,但我不确定哪个位导致问题所以决定添加我认为可能负责的所有部分。当调用disconnect函数时,服务器不会检测到断开连接。然后在断开连接之后,调用connect函数,然后客户端崩溃。

0 个答案:

没有答案