76
Two types of file BIOs are available: buffered and unbuffered. A buffered file BIO is a wrapper around the standard C runtime
FILE
object and its related functions. An unbuffered file BIO is a wrapper around a file descriptor and its related functions. With the exception of how the two
different types of file BIOs are created, the interface for using them is essentially the same. A buffered file BIO can be created by using
BIO_s_file
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. Alternatively,
BIO_new_file
can be used the same way as the standard C runtime function,
fopen
, is used, or
BIO_new_fp
can be used to create a BIO around an already existing
FILE
object. Using
BIO_new_fp
, you must specify the
FILE
object to use and a flag indicating whether the
FILE
object should be closed when the BIO is destroyed.
An unbuffered file BIO can be created by using
BIO_s_fd
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. Alternatively,
BIO_new_fd
can be used in the same way that
BIO_new_fp
cis used for buffered BIOs. The difference is that a file descriptor rather than a
FILE
object must be specified. For either a buffered or an unbuffered file BIO created with
BIO_new
or
BIO_set
, additional work must be done to make the BIO usable. Initially, no underlying file object is attached to the
BIO, and any read or write operations performed on the BIO always fail. Unbuffered file types of BIOs require that
BIO_set_fd
be used to attach a file descriptor to the BIO. Buffered file types of BIOs require that
BIO_set_file
be used to attach a
FILE
object to the BIO, or one of
BIO_read_filename
,
BIO_write_filename
,
BIO_append_filename
, or
BIO_rw_filename
be used to create an underlying
FILE
object with the appropriate mode for the BIO.
Example 4-5 shows how to create a file BIO.
Example 4-5. Creating a file BIO
Create a buffered file BIO with an existing FILE object that will be closed when the BIO is destroyed.
file = fopenfilename.ext, r+; bio = BIO_newBIO_s_file;
BIO_set_filebio, file, BIO_CLOSE; Create an unbuffered file BIO with an existing file descriptor
that will not be closed when the BIO is destroyed. fd = openfilename.ext, O_RDWR;
bio = BIO_newBIO_s_fd; BIO_set_fdbio, fd, BIO_NOCLOSE;
Create a buffered file BIO with a new FILE object owned by the BIO bio = BIO_new_filefilename.ext, w;
Create an unbuffered file BIO with an existing file descriptor that will be closed when the BIO is destroyed.
fd = openfilename.ext, O_RDONLY; bio = BIO_new_fdfd, BIO_CLOSE;
4.3.1.3 Socket sourcessinks
There are three types of socket BIOs. The simplest is a socket BIO that must have an already existing socket descriptor attached to it. Such a BIO can be created using
BIO_s_socket
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. The socket descriptor can then be attached to the BIO using
BIO_set_fd
. This type of BIO works almost like an
77
unbuffered file BIO. Alternatively,
BIO_new_socket
can be used in the same way that
BIO_new_fd
works for unbuffered file BIOs. The second type of BIO socket is a connection socket. This type of BIO creates a new socket that
is initially unconnected. The IP address and port to connect to must be set, and the connection established before data can be read from or written to the BIO.
BIO_s_connect
is used to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. To set the address, either
BIO_set_conn_hostname
can be used to set the hostname or
BIO_set_conn_ip
can be used to set the IP address in dotted decimal form. Both functions take the connection address as a
C-style string. The port to connect to is set using
BIO_set_conn_port
or
BIO_set_conn_int_port
. The difference between the two is that
BIO_set_conn_port
takes the port number as a string, which can be either a port number or a service name such as http or https, and
BIO_set_conn_int_port
takes the port number as an integer. Once the address and port are set for making a connection, an attempt to establish a connection can be made
via
BIO_do_connect
. Once a connection is successfully established, the BIO can be used just as if it was a plain socket BIO.
The third type of BIO socket is an accept socket. This type of BIO creates a new socket that will listen for incoming connections and accept them. When a connection is established, a new BIO
object is created that is bound to the accepted socket. The new BIO object is chained to the original BIO and should be disconnected from the chain before use. Data can be read or written
with the new BIO object. The original BIO object can then be used to accept more connections.
In order to create an accept socket type of socket BIO, use
BIO_s_accept
to obtain a
BIO_METHOD
object suitable for use with
BIO_new
and
BIO_set
. The port used to listen for connections must be set before the BIO can be placed into listening mode. This can be done using
BIO_set_accept_port
, which accepts the port as a string. The port can be either a number or the name of a service, just like with
BIO_set_conn_port
. Once the port is set,
BIO_do_accept
will place the BIOs socket into listening mode. Successive calls to
BIO_do_accept
will block until a new connection is established. Example 4-6
demonstrates.
Example 4-6. Creating a socket BIO
Create a socket BIO attached to an already existing socket descriptor. The socket descriptor will not be closed when the BIO is
destroyed. bio = BIO_newBIO_s_socket;
BIO_set_fdbio, sd, BIO_NOCLOSE; Create a socket BIO attached to an already existing socket
descriptor. The socket descriptor will be closed when the BIO is destroyed.
bio = BIO_new_socketsd, BIO_CLOSE; Create a socket BIO to establish a connection to a remote host.
bio = BIO_newBIO_s_connect; BIO_set_conn_hostnamebio, www.ora.com;
BIO_set_conn_portbio, http; BIO_do_connectbio;
Create a socket BIO to listen for an incoming connection. bio = BIO_newBIO_s_accept;
BIO_set_accept_portbio, https; BIO_do_acceptbio; place the underlying socket into listening
mode for ;;
{
78
BIO_do_acceptbio; wait for a new connection new_bio = BIO_popbio;
new_bio now behaves like a BIO_s_socket BIO }
4.3.1.4 BIO pairs