Beispiel #1
0
    def shutdown_request( self ):
        '''The default SocketServer.shutdown_request does send a shutdown(socket.SHUT_WR), but does NOT
        wait for the socket to drain before closing it, potentially leaving the kernel socket dirty
        (filled with unclaimed data; at least the client's EOF).  Drain the socket, then close it.
        Ignores ENOTCONN (and other) socket.error if socket is already closed.

        '''
        log.detail( "Modbus/TCP client socket shutdown/drain %s", self.client_address )
        network.drain( self.request, timeout=self.drain, close=False )
        self.close_request()
Beispiel #2
0
    def shutdown_request(self):
        '''The default SocketServer.shutdown_request does send a shutdown(socket.SHUT_WR), but does NOT
        wait for the socket to drain before closing it, potentially leaving the kernel socket dirty
        (filled with unclaimed data; at least the client's EOF).  Drain the socket, then close it.
        Ignores ENOTCONN (and other) socket.error if socket is already closed.

        '''
        log.detail("Modbus/TCP client socket shutdown/drain %s",
                   self.client_address)
        network.drain(self.request, timeout=self.drain, close=False)
        self.close_request()
Beispiel #3
0
def echo_cli( number, reps ):
    log.normal( "Echo Client %3d connecting... PID [%5d]", number, os.getpid() )
    conn			= socket.socket( socket.AF_INET, socket.SOCK_STREAM )
    conn.connect( echo.address )
    log.detail( "Echo Client %3d connected", number )
        
    sent			= b''
    rcvd			= b''
    try:
        # Send messages and collect replies 'til done (or incoming EOF).  Then, shut down 
        # outgoing half of socket to drain server and shut down server.
        eof			= False
        for r in range( reps ):
            msg			= ("Client %3d, rep %d\r\n" % ( number, r )).encode()
            log.detail("Echo Client %3d send: %5d: %s", number, len( msg ), cpppo.reprlib.repr( msg ))
            sent	       += msg

            while len( msg ) and not eof:
                out		= min( len( msg ), random.randrange( *charrange ))
                conn.send( msg[:out] )
                msg		= msg[out:]

                # Await inter-block chardelay if output remains, otherwise await final response
                # before dropping out to shutdown/drain/close.  If we drop out immediately and send
                # a socket.shutdown, it'll sometimes deliver a reset to the server end of the
                # socket, before delivering the last of the data.
                rpy		= network.recv( conn, timeout=chardelay if len( msg ) else draindelay )
                if rpy is not None:
                    eof		= not len( rpy )
                    log.detail( "Echo Client %3d recv: %5d: %s", number, len( rpy ),
                              "EOF" if eof else cpppo.reprlib.repr( rpy ))
                    rcvd       += rpy
            if eof:
                break

        log.normal( "Echo Client %3d done; %s", number, "due to EOF" if eof else "normal termination" )

    except KeyboardInterrupt as exc:
        log.warning( "Echo Client %3d terminated: %r", number, exc )
    except Exception as exc:
        log.warning( "Echo Client %3d failed: %r\n%s", number, exc, traceback.format_exc() )
    finally:
        # One or more packets may be in flight; wait 'til we timeout/EOF.  This shuts down conn.
        rpy			= network.drain( conn, timeout=draindelay )
        log.info( "Echo Client %3d drain %5d: %s", number, len( rpy ) if rpy is not None else 0,
                  cpppo.reprlib.repr( rpy ))
        if rpy is not None:
            rcvd   	       += rpy

    # Count the number of success/failures reported by the Echo client threads
    failed			= not ( rcvd == sent )
    if failed:
        log.warning( "Echo Client %3d failed: %s != %s sent", number, cpppo.reprlib.repr( rcvd ),
                     cpppo.reprlib.repr( sent ))
    
    log.info( "Echo Client %3d exited", number )
    return failed
Beispiel #4
0
def tnet_cli(number, tests=None):
    log.info("%3d client connecting... PID [%5d]", number, os.getpid())
    conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    conn.connect(tnet.address)
    log.info("%3d client connected", number)

    rcvd = ''
    try:
        eof = False
        for t in tests:
            msg = tnetstrings.dump(t)

            while len(msg) and not eof:
                out = min(len(msg), random.randrange(*charrange))
                log.info("Tnet Client %3d send: %5d/%5d: %s", number, out,
                         len(msg), cpppo.reprlib.repr(msg[:out]))
                conn.sendall(msg[:out])
                msg = msg[out:]

                # Await inter-block chardelay if output remains, otherwise await
                # final response before dropping out to shutdown/drain/close.
                # If we drop out immediately and send a socket.shutdown, it'll
                # sometimes deliver a reset to the server end of the socket,
                # before delivering the last of the data.
                rpy = network.recv(
                    conn, timeout=chardelay if len(msg) else draindelay)
                if rpy is not None:
                    eof = not len(rpy)
                    log.info("Tnet Client %3d recv: %5d: %s", number, len(rpy),
                             "EOF" if eof else cpppo.reprlib.repr(rpy))
                    rcvd += rpy.decode("utf-8")
            if eof:
                break

        log.normal("Tnet Client %3d done; %s", number,
                   "due to EOF" if eof else "normal termination")

    except KeyboardInterrupt as exc:
        log.normal("%3d client terminated: %r", number, exc)
    except Exception as exc:
        log.warning("%3d client failed: %r\n%s", number, exc,
                    traceback.format_exc())
    finally:
        # One or more packets may be in flight; wait 'til we timeout/EOF
        rpy = network.drain(conn, timeout=draindelay)
        log.info("Tnet Client %3d drain %5d: %s", number,
                 len(rpy) if rpy is not None else 0, cpppo.reprlib.repr(rpy))
        if rpy is not None:
            rcvd += rpy.decode("utf-8")

    # Count the number of successfully matched JSON decodes
    successes = 0
    i = 0
    for i, (t, r) in enumerate(zip(tests, rcvd.split('\n\n'))):
        e = json.dumps(t)
        log.info("%3d test #%3d: %32s --> %s", number, i,
                 cpppo.reprlib.repr(t), cpppo.reprlib.repr(e))
        if r == e:
            successes += 1
        else:
            log.warning("%3d test #%3d: %32s got %s", number, i,
                        cpppo.reprlib.repr(t), cpppo.reprlib.repr(e))

    failed = successes != len(tests)
    if failed:
        log.warning("%3d client failed: %d/%d tests succeeded", number,
                    successes, len(tests))

    log.info("%3d client exited", number)
    return failed
def tnet_cli( number, tests=None ):
    log.info( "%3d client connecting... PID [%5d]", number, os.getpid() )
    conn			= socket.socket( socket.AF_INET, socket.SOCK_STREAM )
    conn.connect( tnet.address )
    log.info( "%3d client connected", number )
        
    rcvd			= ''
    try:
        eof			= False
        for t in tests:
            msg			= tnetstrings.dump( t )
            log.normal( "Tnet Client %3d send: %5d: %s (from data: %s)", number, len( msg ),
                      cpppo.reprlib.repr( msg ), cpppo.reprlib.repr( t ))

            while len( msg ) and not eof:
                out		= min( len( msg ), random.randrange( *charrange ))
                conn.send( msg[:out] )
                msg		= msg[out:]

                # Await inter-block chardelay if output remains, otherwise await
                # final response before dropping out to shutdown/drain/close.
                # If we drop out immediately and send a socket.shutdown, it'll
                # sometimes deliver a reset to the server end of the socket,
                # before delivering the last of the data.
                rpy		= network.recv( conn, timeout=chardelay if len( msg ) else draindelay )
                if rpy is not None:
                    eof		= not len( rpy )
                    log.info( "Tnet Client %3d recv: %5d: %s", number, len( rpy ),
                              "EOF" if eof else cpppo.reprlib.repr( rpy ))
                    rcvd       += rpy.decode( "utf-8" )
            if eof:
                break

        log.normal( "Tnet Client %3d done; %s", number, "due to EOF" if eof else "normal termination" )

    except KeyboardInterrupt as exc:
        log.normal( "%3d client terminated: %r", number, exc )
    except Exception as exc:
        log.warning( "%3d client failed: %r\n%s", number, exc, traceback.format_exc() )
    finally:
        # One or more packets may be in flight; wait 'til we timeout/EOF
        rpy			= network.drain( conn, timeout=draindelay )
        log.info( "Tnet Client %3d drain %5d: %s", number, len( rpy ) if rpy is not None else 0,
                  cpppo.reprlib.repr( rpy ))
        if rpy is not None:
            rcvd   	       += rpy.decode( "utf-8" )

    # Count the number of successfully matched JSON decodes
    successes			= 0
    i 				= 0
    for i, (t, r) in enumerate( zip( tests, rcvd.split( '\n\n' ))):
        e			= json.dumps( t )
        log.info( "%3d test #%3d: %32s --> %s", number, i, cpppo.reprlib.repr( t ), cpppo.reprlib.repr( e ))
        if r == e:
            successes	       += 1
        else:
            log.warning( "%3d test #%3d: %32s got %s", number, i, cpppo.reprlib.repr( t ), cpppo.reprlib.repr( e ))
        
    failed			= successes != len( tests )
    if failed:
        log.warning( "%3d client failed: %d/%d tests succeeded", number, successes, len( tests ))
    
    log.info( "%3d client exited", number )
    return failed