Потерянный пакет Python - PullRequest
1 голос
/ 17 июня 2011

Я пытался написать клиент-серверное приложение на Python, но столкнулся с проблемой: на стороне клиента я не получаю все отправленные данные.Сначала я попытался отправить числа от 1 до 10, и я получил 1,2,5,6,10, поэтому пропущено много номеров.

Сторона сервера:

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

1 Ответ

2 голосов
/ 17 июня 2011

Сервер может отправить несколько сообщений к тому времени, когда клиент попытается их прочитать, и если они помещаются в один и тот же буфер 4 КБ, вызов recv() получит оба из них.

Вы не 'Я не могу показать код getMessage, но я предполагаю, что вы делаете что-то вроде pickle.loads(msg), но это даст вам только первое сообщение и отбросит остальную часть строки, отсюда и пропущенные сообщения.Вы также получите другую проблему, если к моменту прочтения будет буферизовано более 4096 байт, так как в итоге вы можете получить фрагмент сообщения и, следовательно, ошибку удаления.

Вам нужно будет разбитьСтрока, которую вы возвращаете в отдельные сообщения, или, что еще лучше, просто обрабатывает сокет как поток и позволяет pickle.load извлечь из него одно сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...