2011-06-17 120 views
1

我试图在Python中编写客户端服务器应用程序,但我遇到了一个问题,在客户端,我没有得到所有发送的数据。首先我试着发送1到10的数字,我收到1,2,5,6,10,所以缺少很多数字。Python丢失包

服务器端:

def __init__(self): 
     super(MCCommunication, self).__init__() 

     HOST, PORT = socket.gethostbyname(socket.gethostname()), 31000 
     self.server = SocketServer.ThreadingTCPServer((HOST, PORT), MCRequestHandler) 
     ip, port = self.server.server_address   
     # Start a thread with the server 
     # Future task: Make the server a QT-Thread... 
     self.server_thread = threading.Thread(target = self.server.serve_forever) 
     # Exit the server thread when the main thread terminates 
     self.server_thread.setDaemon(True) 
     self.textUpdated.emit('Server Started!') 
     print('Server Started!') 
     self.server_thread.start() 

def handle(self):  
     #self.request.setblocking(0) 
     i = 10; 
     while True: 
      if(self.clientname == 'MasterClient'):     
       try:      
        #ans = self.request.recv(4096) 
        #print('after recv') 
        """ Sendign data, testing purpose """     
        while i: 
         mess = str(i);    
         postbox['MasterClient'].put(self.creatMessage(0, 0 , mess)) 
         i = i - 1 

        while(postbox['MasterClient'].empty() != True):       
         sendData = postbox['MasterClient'].get_nowait()       

         a = self.request.send(sendData) 
         print(a); 
         #dic = self.getMessage(sendData) 
         #print 'Sent:%s\n' % str(dic)       
       except:      
        mess = str(sys.exc_info()[0]) 
        postbox['MasterClient'].put(self.creatMessage(1, 0 , mess)) 
        pass 

    def creatMessage(self, type1 = 0, type2 = 0, message = ' ', extra = 0):   
     return pickle.dumps({"type1":type1, "type2":type2, "message":message, "extra":extra}); 

postbox['MasterClient']是与序列化消息的队列。

这是客户端:

def run(self):   
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   
     addr = (self.ip, self.port)   
     #print addr 
     sock.connect(addr) 
     #sock.setblocking(0) 
     while True:   
      try: 
       ans = sock.recv(4096)     
       dic = self.getMessage(ans)    
       self.recvMessageHandler(dic) 
       print 'Received:%s\n' % str(dic)  
      except: 
       pass 

回答

2

服务器可能已经由客户端尝试读取它们时发送多条消息,如果这些符合相同的4K缓冲,而recv()电话将同时获得其中。

您不显示getMessage代码,但我猜你正在做类似pickle.loads(msg)的操作,但这只会给你第一条消息并丢弃字符串的其余部分,因此会丢失消息。如果读取的时间超过4096字节,您还会得到另一个问题,因为您最终可能会得到一条消息的片段,从而导致不可纠正的错误。

您需要分解返回到单独消息中的字符串,或者更好的是,将套接字视为流,然后让其从中取出单条消息。