High-level interface to libuv's TCP functionality

Type ConnectReqData

type ConnectReqData = {result_ch: comm::Chan<ConnAttempt>, closed_signal_ch: comm::Chan<()>,}

Type TcpBufferedSocketData

type TcpBufferedSocketData = {sock: TcpSocket, mut buf: ~[u8],}

Type TcpErrData

type TcpErrData = {err_name: ~str, err_msg: ~str,}

Contains raw, string-based, error information returned from libuv

Type TcpListenFcData

type TcpListenFcData = {server_stream_ptr: *uv::ll::uv_tcp_t,
 stream_closed_ch: comm::Chan<()>,
 kill_ch: comm::Chan<Option<TcpErrData>>,
 on_connect_cb: fn~(*uv::ll::uv_tcp_t),
 iotask: IoTask,
 mut active: bool,}

Type TcpSocketCloseData

type TcpSocketCloseData = {closed_ch: comm::Chan<()>,}

Type TcpSocketData

type TcpSocketData = {reader_po: comm::Port<result::Result<~[u8], TcpErrData>>,
 reader_ch: comm::Chan<result::Result<~[u8], TcpErrData>>,
 stream_handle_ptr: *uv::ll::uv_tcp_t,
 connect_req: uv::ll::uv_connect_t,
 write_req: uv::ll::uv_write_t,
 iotask: IoTask,}

Type WriteReqData

type WriteReqData = {result_ch: comm::Chan<TcpWriteResult>,}

Enum ConnAttempt

Variants

Enum TcpConnectErrData

Details returned as part of a result::err result from tcp::connect

Variants

Enum TcpConnectResult

Variants

Enum TcpListenErrData

Details returned as part of a result::err result from tcp::listen

Variants

Possible Causes

Possible Causes

Enum TcpNewConnection

Variants

  • NewTcpConn(*uv::ll::uv_tcp_t)

Enum TcpReadResult

Variants

  • TcpReadData(~[u8])
  • TcpReadDone
  • TcpReadErr(TcpErrData)

Enum TcpReadStartResult

Variants

  • TcpReadStartSuccess(comm::Port<TcpReadResult>)
  • TcpReadStartError(TcpErrData)

Enum TcpWriteResult

Variants

  • TcpWriteSuccess
  • TcpWriteError(TcpErrData)

Struct TcpSocket

struct TcpSocket {
    socket_data: @TcpSocketData,
}

Encapsulates an open TCP/IP connection through libuv

tcp_socket is non-copyable/sendable and automagically handles closing the underlying libuv data structures when it goes out of scope. This is the data structure that is used for read/write operations over a TCP stream.

Struct TcpSocketBuf

struct TcpSocketBuf {
    data: @TcpBufferedSocketData,
}

A buffered wrapper for net::tcp::tcp_socket

It is created with a call to net::tcp::socket_buf() and has impls that satisfy both the io::reader and io::writer traits.

Interface ToTcpErr

Method to_tcp_err

fn to_tcp_err() -> TcpErrData

Implementation for TcpSocket

Convenience methods extending net::tcp::tcp_socket

Method read_start

fn read_start() ->
   result::Result<comm::Port<result::Result<~[u8], TcpErrData>>, TcpErrData>

Method read_stop

fn read_stop(read_port: comm::Port<result::Result<~[u8], TcpErrData>>) ->
   result::Result<(), TcpErrData>

Method read

fn read(timeout_msecs: uint) -> result::Result<~[u8], TcpErrData>

Method read_future

fn read_future(timeout_msecs: uint) ->
   future::Future<result::Result<~[u8], TcpErrData>>

Method write

fn write(raw_write_data: ~[u8]) -> result::Result<(), TcpErrData>

Method write_future

fn write_future(raw_write_data: ~[u8]) ->
   future::Future<result::Result<(), TcpErrData>>

Implementation of io::Reader for TcpSocketBuf

Implementation of io::reader trait for a buffered net::tcp::tcp_socket

Method read

fn read(buf: & [mut u8], len: uint) -> uint

Method read_byte

fn read_byte() -> int

Method unread_byte

fn unread_byte(amt: int)

Method eof

fn eof() -> bool

Method seek

fn seek(dist: int, seek: io::SeekStyle)

Method tell

fn tell() -> uint

Implementation of io::Writer for TcpSocketBuf

Implementation of io::reader trait for a buffered net::tcp::tcp_socket

Method write

fn write(data: & [const u8])

Method seek

fn seek(dist: int, seek: io::SeekStyle)

Method tell

fn tell() -> uint

Method flush

fn flush() -> int

Method get_type

fn get_type() -> io::WriterType

Implementation of ToTcpErr for uv::ll::uv_err_data

Method to_tcp_err

fn to_tcp_err() -> TcpErrData

Function TcpSocket

fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket

Function TcpSocketBuf

fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf

Function accept

fn accept(new_conn: TcpNewConnection) -> result::Result<TcpSocket, TcpErrData>

Bind an incoming client connection to a net::tcp::tcp_socket

Notes

It is safe to call net::tcp::accept only within the context of the new_connect_cb callback provided as the final argument to the net::tcp::listen function.

The new_conn opaque value is provided only as the first argument to the new_connect_cb provided as a part of net::tcp::listen. It can be safely sent to another task but it must be used (via net::tcp::accept) before the new_connect_cb call it was provided to returns.

This implies that a port/chan pair must be used to make sure that the new_connect_cb call blocks until an attempt to create a net::tcp::tcp_socket is completed.

Example

Here, the new_conn is used in conjunction with accept from within a task spawned by the new_connect_cb passed into listen

net::tcp::listen(remote_ip, remote_port, backlog)
    // this callback is ran once after the connection is successfully
    // set up
    {|kill_ch|
      // pass the kill_ch to your main loop or wherever you want
      // to be able to externally kill the server from
    }
    // this callback is ran when a new connection arrives
    {|new_conn, kill_ch|
    let cont_po = core::comm::port::<option<tcp_err_data>>();
    let cont_ch = core::comm::chan(cont_po);
    task::spawn {||
        let accept_result = net::tcp::accept(new_conn);
        if accept_result.is_err() {
            core::comm::send(cont_ch, result::get_err(accept_result));
            // fail?
        }
        else {
            let sock = result::get(accept_result);
            core::comm::send(cont_ch, true);
            // do work here
        }
    };
    match core::comm::recv(cont_po) {
      // shut down listen()
      some(err_data) { core::comm::send(kill_chan, some(err_data)) }
      // wait for next connection
      none {}
    }
};

Arguments

  • new_conn - an opaque value used to create a new tcp_socket

Returns

On success, this function will return a net::tcp::tcp_socket as the ok variant of a result. The net::tcp::tcp_socket is anchored within the task that accept was called within for its lifetime. On failure, this function will return a net::tcp::tcp_err_data record as the err variant of a result.

Function connect

fn connect(input_ip: ip::IpAddr, port: uint, iotask: IoTask) ->
   result::Result<TcpSocket, TcpConnectErrData>

Initiate a client connection over TCP/IP

Arguments

  • input_ip - The IP address (versions 4 or 6) of the remote host
  • port - the unsigned integer of the desired remote host port
  • iotask - a uv::iotask that the tcp request will run on

Returns

A result that, if the operation succeeds, contains a net::net::tcp_socket that can be used to send and receive data to/from the remote host. In the event of failure, a net::tcp::tcp_connect_err_data instance will be returned

Function listen

fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, iotask: IoTask,
          on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
          new_connect_cb:
              fn~(TcpNewConnection, comm::Chan<Option<TcpErrData>>)) ->
   result::Result<(), TcpListenErrData>

Bind to a given IP/port and listen for new connections

Arguments

  • host_ip - a net::ip::ip_addr representing a unique IP (versions 4 or 6)
  • port - a uint representing the port to listen on
  • backlog - a uint representing the number of incoming connections to cache in memory
  • hl_loop - a uv::hl::high_level_loop that the tcp request will run on
  • on_establish_cb - a callback that is evaluated if/when the listener is successfully established. it takes no parameters
  • new_connect_cb - a callback to be evaluated, on the libuv thread, whenever a client attempts to conect on the provided ip/port. the callback's arguments are:
    • new_conn - an opaque type that can be passed to net::tcp::accept in order to be converted to a tcp_socket.
    • kill_ch - channel of type core::comm::chan<option<tcp_err_data>>. this channel can be used to send a message to cause listen to begin closing the underlying libuv data structures.

returns

a result instance containing empty data of type () on a successful/normal shutdown, and a tcp_listen_err_data enum in the event of listen exiting because of an error

Function listen_common

fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
                 iotask: IoTask,
                 on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
                 on_connect_cb: fn~(*uv::ll::uv_tcp_t)) ->
   result::Result<(), TcpListenErrData>

Function malloc_uv_tcp_t

fn malloc_uv_tcp_t() -> *uv::ll::uv_tcp_t

Function on_alloc_cb

fn on_alloc_cb(handle: *libc::c_void, suggested_size: size_t) ->
   uv::ll::uv_buf_t

Function on_tcp_read_cb

fn on_tcp_read_cb(stream: *uv::ll::uv_stream_t, nread: libc::ssize_t,
                  ++buf: uv::ll::uv_buf_t)

Function read

fn read(sock: & TcpSocket, timeout_msecs: uint) ->
   result::Result<~[u8], TcpErrData>

Reads a single chunk of data from tcp_socket; block until data/error recv'd

Does a blocking read operation for a single chunk of data from a tcp_socket until a data arrives or an error is received. The provided timeout_msecs value is used to raise an error if the timeout period passes without any data received.

Arguments

  • sock - a net::tcp::tcp_socket that you wish to read from
  • timeout_msecs - a uint value, in msecs, to wait before dropping the read attempt. Pass 0u to wait indefinitely

Function read_common_impl

fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) ->
   result::Result<~[u8], TcpErrData>

Function read_future

fn read_future(sock: & TcpSocket, timeout_msecs: uint) ->
   future::Future<result::Result<~[u8], TcpErrData>>

Reads a single chunk of data; returns a future::future<~[u8]> immediately

Does a non-blocking read operation for a single chunk of data from a tcp_socket and immediately returns a future value representing the result. When resolving the returned future, it will block until data arrives or an error is received. The provided timeout_msecs value is used to raise an error if the timeout period passes without any data received.

Safety

This function can produce unsafe results if the call to read_future is made, the future::future value returned is never resolved via future::get, and then the tcp_socket passed in to read_future leaves scope and is destructed before the task that runs the libuv read operation completes.

As such: If using read_future, always be sure to resolve the returned future so as to ensure libuv doesn't try to access a released read handle. Otherwise, use the blocking tcp::read function instead.

Arguments

  • sock - a net::tcp::tcp_socket that you wish to read from
  • timeout_msecs - a uint value, in msecs, to wait before dropping the read attempt. Pass 0u to wait indefinitely

Function read_start

fn read_start(sock: & TcpSocket) ->
   result::Result<comm::Port<result::Result<~[u8], TcpErrData>>, TcpErrData>

Begin reading binary data from an open TCP connection; used with read_stop

Arguments

  • sock -- a net::tcp::tcp_socket for the connection to read from

Returns

  • A result instance that will either contain a core::comm::port<tcp_read_result> that the user can read (and optionally, loop on) from until read_stop is called, or a tcp_err_data record

Function read_start_common_impl

fn read_start_common_impl(socket_data: *TcpSocketData) ->
   result::Result<comm::Port<result::Result<~[u8], TcpErrData>>, TcpErrData>

Function read_stop

fn read_stop(sock: & TcpSocket,
             read_port: comm::Port<result::Result<~[u8], TcpErrData>>) ->
   result::Result<(), TcpErrData>

Stop reading from an open TCP connection; used with read_start

Arguments

  • sock - a net::tcp::tcp_socket that you wish to stop reading on

Function read_stop_common_impl

fn read_stop_common_impl(socket_data: *TcpSocketData) ->
   result::Result<(), TcpErrData>

Function socket_buf

fn socket_buf(sock: TcpSocket) -> TcpSocketBuf

Convert a net::tcp::tcp_socket to a net::tcp::tcp_socket_buf.

This function takes ownership of a net::tcp::tcp_socket, returning it stored within a buffered wrapper, which can be converted to a io::reader or io::writer

Arguments

  • sock -- a net::tcp::tcp_socket that you want to buffer

Returns

A buffered wrapper that you can cast as an io::reader or io::writer

Function stream_error_close_cb

fn stream_error_close_cb(handle: *uv::ll::uv_tcp_t)

Function tcp_connect_close_cb

fn tcp_connect_close_cb(handle: *uv::ll::uv_tcp_t)

Function tcp_connect_on_connect_cb

fn tcp_connect_on_connect_cb(connect_req_ptr: *uv::ll::uv_connect_t,
                             status: libc::c_int)

Function tcp_lfc_close_cb

fn tcp_lfc_close_cb(handle: *uv::ll::uv_tcp_t)

Function tcp_lfc_on_connection_cb

fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t, status: libc::c_int)

Function tcp_socket_dtor_close_cb

fn tcp_socket_dtor_close_cb(handle: *uv::ll::uv_tcp_t)

Function tcp_write_complete_cb

fn tcp_write_complete_cb(write_req: *uv::ll::uv_write_t, status: libc::c_int)

Function tear_down_socket_data

fn tear_down_socket_data(socket_data: @TcpSocketData)

Function write

fn write(sock: & TcpSocket, raw_write_data: ~[u8]) ->
   result::Result<(), TcpErrData>

Write binary data to a tcp stream; Blocks until operation completes

Arguments

  • sock - a tcp_socket to write to
  • raw_write_data - a vector of ~[u8] that will be written to the stream. This value must remain valid for the duration of the write call

Returns

A result object with a nil value as the ok variant, or a tcp_err_data value as the err variant

Function write_common_impl

fn write_common_impl(socket_data_ptr: *TcpSocketData, raw_write_data: ~[u8])
   -> result::Result<(), TcpErrData>

Function write_future

fn write_future(sock: & TcpSocket, raw_write_data: ~[u8]) ->
   future::Future<result::Result<(), TcpErrData>>

Write binary data to tcp stream; Returns a future::future value immediately

Safety

This function can produce unsafe results if:

  1. the call to write_future is made
  2. the future::future value returned is never resolved via future::get
  3. and then the tcp_socket passed in to write_future leaves scope and is destructed before the task that runs the libuv write operation completes.

As such: If using write_future, always be sure to resolve the returned future so as to ensure libuv doesn't try to access a released write handle. Otherwise, use the blocking tcp::write function instead.

Arguments

  • sock - a tcp_socket to write to
  • raw_write_data - a vector of ~[u8] that will be written to the stream. This value must remain valid for the duration of the write call

Returns

A future value that, once the write operation completes, resolves to a result object with a nil value as the ok variant, or a tcp_err_data value as the err variant