2012-01-20 41 views
2

我需要建立一個python聊天,我堆放在最後一步。我已經建立了服務器和客戶端和我有以下問題,同時運行代碼:使用民意調查蟒蛇聊天

  • server.py 127.0.0.1 -in一個單獨的窗口client.py 127.0.0.1 -another客戶 - 鍵入暱稱聊客戶和得到正確的答案「雅痞」,意思是你連接
  • 客戶儘量放慢說話
  • 消息不被其他客戶端讀取,直到它不打印東西,打印後正確地在屏幕上顯示消息。

我想得到的消息沒有被迫打印的東西,這是非常不現實的!客戶端和服務器的代碼在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() 
+0

解決!這是輸出沖洗的問題!它在客戶端方法聊天的同時很好地添加了sys.stdout.flush(),或者始終以相同的聊天方法從打印中刪除逗號(\ n刷新輸出) –

回答