Bad value on output port 'tcp_inet'

Scott Lystig Fritchie <>
Wed Aug 16 02:30:36 CEST 2006


>>>>> "ms" == Matthew Sackman <> writes:

ms> The documentation is wrong though: gen_tcp:send/2 will actually
ms> accept any arbitrary combination of lists, chars and
ms> binaries.

The 'inets' driver for dealing with sockets uses the same data
structure as the 'file' module uses.  See
http://www.snookles.com/erlang-docs/R10B-9/lib/kernel-2.10.12/doc/html/index.html

    MODULE
      file 
    
    [...]
    
    DATA TYPES
      iodata() = iolist() | binary()
        iolist() = [char() | binary() | iolist()]

Anyone using the name "I/O list" (including me) really means iodata()
above, despite the fact that a single binary term is, by definition,
not a list.

ms> gen_tcp:send(Sock, <<Binary1/binary, Binary2/binary>>),

... will create new binary *and* copy the data from Binary1 and
Binary2 into it.  Then the inets driver will use write(2) or send(2)
or equivalent to copy that data again (into kernel space).

ms> gen_tcp:send(Sock, [Binary1, Binary2]),

... will allocate two cons cells, link 'em together, and stuff
pointers to Binary1 and Binary2 into the appropriate cells.  The
'inets' driver, may (at its discretion(*)) create a "struct iovec"
then call writev(2) or equivalent to copy the data only once (into
kernel space).

-Scott

(*) IIRC, 'inets' tries pretty hard to use "struct iovec" whenever
possible.  Alas, most OSes limit the size of an iovec, which can be
annoying when it's so easy for Erlang to create an I/O list that may
be hundreds of terms long (and/or deep).  So, should inets re-copy
some buffers to fit inside the constrained iovec array, or should it
call writev(2) multiple times?  {shrug} An exercise left for the
reader.



More information about the erlang-questions mailing list