--- 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) :
"""