python聊天使用民意调查

时间:2012-01-20 22:08:09

标签: python chat

我需要建立一个python聊天,我在最后一步堆叠起来。我已经构建了服务器和客户端,运行代码时遇到以下问题:

  • server.py 127.0.0.1 - 在一个单独的窗口client.py 127.0.0.1 - 另一个客户 - 键入两个客户聊天的昵称,并获得正确答案'yuppie',表示您已连接
  • 客户试图发言
  • 消息不会被其他客户端读取,直到它没有打印出来,打印完成后才会正确地在屏幕上打印消息。

我想得到的信息没有被迫打印的东西,这是非常不现实的!客户端和服务器的代码在以下2个不同的类中。谢谢!

#! /usr/bin/env python

import socket,sys,select,re

PORT=1060  

class Server():


    def __init__(self,host):
        #building listen_sock  
        self.listen_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.listen_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.listen_sock.bind((host,PORT))
        self.listen_sock.listen(20)
        #building dict for socket and socket state
        self.sockets={self.listen_sock.fileno(): self.listen_sock}
        self.socket_state={self.listen_sock.fileno():''}
        #building poll object
        self.poll=select.poll()
        self.poll.register(self.listen_sock,select.POLLIN)
        #users' list
        self.users_list={}



        #DON'T LOOK HERE
        #initialize the sender
        #self.sender=0

     #   self.users=re.compile("\s*\$(get users connected)$\s*",re.IGNORECASE)
      #  self.nick=re.compile("\s*\$\$(\w*\d*)\$\$\s*",re.IGNORECASE)
       # self.quit=re.compile("\s*\$(quit)\$\s*",re.IGNORECASE)
        #self.commands=[self.users,self.nick,self.quit]




    #funcion to receive message from client (work well)
    def recv_until(self,fd,suffix):
        self.message=''
        #checking the end of the message
        while not self.message.endswith(suffix):
            data=self.sockets[fd].recv(16)
            if not data:
                raise EOFError('socket closed before we saw %r' % suffix)
            self.message+=data    
        self.message=self.message[:-1]


   #delete client (work well)
    def del_client(self,fd):
        del self.users_list[fd]
        del self.socket_state[fd]
        self.poll.unregister(fd)

       #print the remaining active connections
        if not len(self.users_list):
            print 'Anyone is connected, waiting for new connection'
        else:
            print self.users_list



    #add new client and change the of the file descriptor for that client (work well)
    def new_client(self,fd):
        newsock, sockname = self.listen_sock.accept()
        print 'new connection from ', newsock.getpeername()
        newsock.setblocking(False)
        #recording the new connection
        fd=newsock.fileno()
        self.sockets[fd]=newsock
        self.poll.register(fd,select.POLLOUT)
        self.socket_state[fd]='ask nick'




 #DON'T LOOK HERE 
 #   def handle_query(self,fd):


  #      for n,command in enumerate(self.commands):

   #         match=command.search(self.message)


    #        if n==1 and match:

     #           self.users_list[self.sockets[fd].getpeername()]=match.group(1)
      #          print self.users_list

       #         for value in self.users_list.values():
        #            self.sockets[fd].sendall(value+'\n')




    #starting the main function of the class
    def chat(self):

        while True: 
            #here il where the code hangs up waitng and waiting (WORKS BAD)
            #return a tuple, identify where (fd) the event (event) is happening
            for fd,event in self.poll.poll():
                #print the state of each socket and the poll object
                print self.socket_state
                print self.poll.poll()


                #starting the state machine

                #remove closed sockets
                if event & (select.POLLHUP | select.POLLERR | 
                select.POLLNVAL): 
                    #deleting the socket closed at fd
                    self.del_client(fd)


                #if the socket referred to is our listen_sock and we have a new connection request   
                elif self.sockets[fd] is self.listen_sock:
                    #recording the new entry!
                    self.new_client(fd)




                #managing all the situation where it is necessary to answer to a client
                #and changing the state of the socket and that of the sockets[fd]
                elif event & select.POLLOUT:

                    if self.socket_state[fd]=='ask nick':
                        self.sockets[fd].sendall('identify\n')
                        self.poll.modify(self.sockets[fd],select.POLLIN)
                        self.socket_state[fd]='get user'

                    if self.socket_state[fd]=='invalid nick':
                        self.sockets[fd].sendall('invalid nick\n')
                        for value in self.users_list.values():
                            self.sockets[fd].sendall('\n'+value+'\n')
                        self.socket_state[fd]='ask nick'

                    if self.socket_state[fd]=='connected':
                        print '3'
                        self.sockets[fd].sendall('yuppie\n')
                        self.poll.modify(self.sockets[fd],select.POLLIN)
                        self.socket_state[fd]='ready to communicate'

                    if self.socket_state[fd]=='ready to receive':
                        self.sockets[fd].sendall(self.message)
                        print '4'
                        self.poll.modify(self.sockets[fd],select.POLLIN)
                        self.socket_state[fd]='ready to communicate'




                #managing all the situation where it is necessary to get values from clients
                elif event & select.POLLIN:

                    if self.socket_state[fd]=='get user':

                        self.recv_until(fd,'\n')

                        if self.message not in self.users_list.values():
                            self.users_list[fd]=self.message
                            self.poll.modify(self.sockets[fd],select.POLLOUT)
                            self.socket_state[fd]='connected'
                        else:
                            self.poll.modify(self.sockets[fd],select.POLLOUT)
                            self.socket_state[fd]='invalid nick'

                    if self.socket_state[fd]=='ready to communicate':
                        self.recv_until(fd,'\n')
                        print '5'
                        for i in self.users_list.keys():
                            if i!=fd:
                                self.poll.modify(self.sockets[i],select.POLLOUT)
                                self.socket_state[i]='ready to receive'




if __name__ == '__main__':
    se=Server(sys.argv[1])
    se.chat()






#! /usr/bin/env python

import sys,socket,select,threading,time

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

HOST=sys.argv.pop()
PORT=1060


class Client():


    def setup(self):

        server_address=(HOST,PORT)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect(server_address)



    def chat(self):
        while True:
            time.sleep(1)
            text=raw_input('>>> ')
            self.sock.sendall(text+'\n')




    def rec(self):
        while True:
            mess=self.sock.recv(16)
            if mess:
                print '$$$ ', mess,


    def start(self):
        l=threading.Thread(target=self.rec)
        t=threading.Thread(target=self.chat)


        t.start()
        l.start()


if __name__=='__main__':
    cl=Client()
    cl.setup()
    cl.start()

1 个答案:

答案 0 :(得分:0)

下次看一下http://www.zeromq.org/,它有一个很好的python绑定http://zeromq.github.com/pyzmq/。它非常适合这种东西。