examples/nc.py
changeset 55 99c4344a35ce
parent 54 e7c136812b0d
child 58 ecd89f9605ac
equal deleted inserted replaced
54:e7c136812b0d 55:99c4344a35ce
    17 options = None
    17 options = None
    18 
    18 
    19 # global event_base
    19 # global event_base
    20 ev_base = base.event_base()
    20 ev_base = base.event_base()
    21 
    21 
       
    22 # buffer size to use, 4k - perhaps slightly smaller
       
    23 BUFSIZE = 4 * 1024
    22 
    24 
    23 def parse_argv (argv) :
    25 def parse_argv (argv) :
    24     global options
    26     global options
    25 
    27 
    26     prog = argv.pop(0)
    28     prog = argv.pop(0)
   111 
   113 
   112         else :
   114         else :
   113             # yay
   115             # yay
   114             yield sock
   116             yield sock
   115 
   117 
       
   118 
       
   119 def client_connect_next (sock_iter) :
       
   120     """
       
   121         Attempt to run the given connect operation, on the given iterable of sockets.
       
   122     """
       
   123 
       
   124     for sock in sock_iter :
       
   125         # pend for writing
       
   126         log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock)
       
   127         ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter)
       
   128 
       
   129         # wait specified timeout
       
   130         log_debug("client_connect_next: %r: add(%s)", ev, options.timeout)
       
   131         ev.add(options.timeout)
       
   132 
       
   133         # ok
       
   134         break
       
   135 
       
   136     else :
       
   137         # fail, ran out of addresses to try
       
   138         log_err("client_connect_next: ran out of addresses to try")
       
   139 
       
   140 
   116 def on_connect (ev, events, sock, sock_iter) :
   141 def on_connect (ev, events, sock, sock_iter) :
   117     """
   142     """
   118         Outbound connect EV_WRITE callback, i.e. connection failed or was established
   143         Outbound connect EV_WRITE callback, i.e. connection failed or was established
   119     """
   144     """
   120 
   145 
   138         # keep trying
   163         # keep trying
   139         return client_connect_next(sock_iter)
   164         return client_connect_next(sock_iter)
   140 
   165 
   141 
   166 
   142     # ok, connected
   167     # ok, connected
   143     log_info("on_connect: connected")
   168     client_connected(sock)
   144 
   169 
   145 
   170 
   146 def client_connect_next (sock_iter) :
   171 def client_connected (sock) :
   147     """
   172     """
   148         Attempt to run the given connect operation, on the given iterable of sockets.
   173         Connection established, start shovelling data
   149     """
   174     """
   150 
   175 
   151     for sock in sock_iter :
   176     log_info("Client connected to %s (from %s)", sock.getpeername(), sock.getsockname())
   152         # pend for writing
   177     
   153         log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock)
   178     # go!
   154         ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter)
   179     start_sock(sock, sys.stdin.fileno(), sys.stdout.fileno())
   155 
   180 
   156         # wait specified timeout
   181 
   157         log_debug("client_connect_next: %r: add(%s)", ev, options.timeout)
   182 def start_sock (sock, fd_in, fd_out) :
   158         ev.add(options.timeout)
   183     """
   159 
   184         Start shipping data between sock and fin/fout.
   160         # ok
   185     """
   161         break
   186 
   162 
   187     # event for each
   163     else :
   188     ev_in = cb_event(ev_base, fd_in, EV_READ, on_read_in, sock, fd_in)
   164         # fail, ran out of addresses to try
   189     ev_out = cb_event(ev_base, sock.fd, EV_READ, on_read_sock, sock, fd_out)
   165         log_err("client_connect_next: ran out of addresses to try")
   190 
       
   191     ev_in.add()
       
   192     ev_out.add()
       
   193 
       
   194 
       
   195 def on_read_in (ev, events, sock, fd_in) :
       
   196     """
       
   197         Data readable on ev.fd, ship to sock
       
   198     """
       
   199     
       
   200     # no timeouts yet
       
   201     assert events & EV_READ
       
   202     
       
   203     # try and read
       
   204     buf = os.read(fd_in, BUFSIZE)
       
   205 
       
   206     if buf :
       
   207         # pass on
       
   208         assert sock.write(buf) == len(buf)
       
   209 
       
   210         # keep going
       
   211         ev.add()
       
   212 
       
   213     else :
       
   214         # EOF
       
   215         sock.shutdown(SHUT_WR)
       
   216 
       
   217 
       
   218 def on_read_sock (ev, events, sock, fd_out) :
       
   219     """
       
   220         Data readable on sock, ship to fd_out
       
   221     """
       
   222     
       
   223     # no timeouts yet
       
   224     assert events & EV_READ
       
   225 
       
   226     # try and read
       
   227     buf = sock.read(BUFSIZE)
       
   228 
       
   229     if buf :
       
   230         # pass on
       
   231         assert os.write(fd_out, buf) == len(buf)
       
   232 
       
   233         # keep going
       
   234         ev.add()
       
   235 
       
   236     else :
       
   237         # EOF
       
   238         os.close(fd_out)
       
   239         
       
   240         log_info("EOF from %s", sock.getpeername())
   166 
   241 
   167 def run_client (host, port) :
   242 def run_client (host, port) :
   168     """
   243     """
   169         Execute in client-mode
   244         Execute in client-mode
   170     """
   245     """