# HG changeset patch # User Tero Marttila # Date 1253992164 -10800 # Node ID 99c4344a35cea562f01c0e309560c25828e4898e # Parent e7c136812b0d87734b9c28eb374eebd3e14d6653 nc.py is now functional enough for basic client use diff -r e7c136812b0d -r 99c4344a35ce examples/nc.py --- a/examples/nc.py Sat Sep 26 21:52:06 2009 +0300 +++ b/examples/nc.py Sat Sep 26 22:09:24 2009 +0300 @@ -19,6 +19,8 @@ # global event_base ev_base = base.event_base() +# buffer size to use, 4k - perhaps slightly smaller +BUFSIZE = 4 * 1024 def parse_argv (argv) : global options @@ -113,6 +115,29 @@ # yay yield sock + +def client_connect_next (sock_iter) : + """ + Attempt to run the given connect operation, on the given iterable of sockets. + """ + + for sock in sock_iter : + # pend for writing + log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock) + ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter) + + # wait specified timeout + log_debug("client_connect_next: %r: add(%s)", ev, options.timeout) + ev.add(options.timeout) + + # ok + break + + else : + # fail, ran out of addresses to try + log_err("client_connect_next: ran out of addresses to try") + + def on_connect (ev, events, sock, sock_iter) : """ Outbound connect EV_WRITE callback, i.e. connection failed or was established @@ -140,29 +165,79 @@ # ok, connected - log_info("on_connect: connected") + client_connected(sock) -def client_connect_next (sock_iter) : +def client_connected (sock) : """ - Attempt to run the given connect operation, on the given iterable of sockets. + Connection established, start shovelling data """ - for sock in sock_iter : - # pend for writing - log_debug("client_connect_next: cb_event(%d, EV_WRITE, on_connect, %r)", sock.fd, sock) - ev = cb_event(ev_base, sock.fd, EV_WRITE, on_connect, sock, sock_iter) + log_info("Client connected to %s (from %s)", sock.getpeername(), sock.getsockname()) + + # go! + start_sock(sock, sys.stdin.fileno(), sys.stdout.fileno()) - # wait specified timeout - log_debug("client_connect_next: %r: add(%s)", ev, options.timeout) - ev.add(options.timeout) - # ok - break +def start_sock (sock, fd_in, fd_out) : + """ + Start shipping data between sock and fin/fout. + """ + + # event for each + ev_in = cb_event(ev_base, fd_in, EV_READ, on_read_in, sock, fd_in) + ev_out = cb_event(ev_base, sock.fd, EV_READ, on_read_sock, sock, fd_out) + + ev_in.add() + ev_out.add() + + +def on_read_in (ev, events, sock, fd_in) : + """ + Data readable on ev.fd, ship to sock + """ + + # no timeouts yet + assert events & EV_READ + + # try and read + buf = os.read(fd_in, BUFSIZE) + + if buf : + # pass on + assert sock.write(buf) == len(buf) + + # keep going + ev.add() else : - # fail, ran out of addresses to try - log_err("client_connect_next: ran out of addresses to try") + # EOF + sock.shutdown(SHUT_WR) + + +def on_read_sock (ev, events, sock, fd_out) : + """ + Data readable on sock, ship to fd_out + """ + + # no timeouts yet + assert events & EV_READ + + # try and read + buf = sock.read(BUFSIZE) + + if buf : + # pass on + assert os.write(fd_out, buf) == len(buf) + + # keep going + ev.add() + + else : + # EOF + os.close(fd_out) + + log_info("EOF from %s", sock.getpeername()) def run_client (host, port) : """