Networking Tools: Network Communication Classes (net library)
#include <rw/toolpro/socket.h> RWSocket socket;
net, tls (and possibly std)
RWSocket is a wrapper for the C concept of a socket. Its member functions correspond exactly with the C functions in the Berkeley sockets API. Typically, RWSocket member functions have the same names as the corresponding C API functions, but the arguments and return values may be different to reflect the C++ environment. For example, many member functions have default arguments to handle the most common cases. Some member functions take alternate parameter types that simplify the interface (for example, using the RWSockAddrBase class instead of the sockaddr structure.). Sometimes, multiple overloadings of a member function exist to provide alternate APIs for different occasions.
Almost all of the Berkeley sockets calls that deal with a single socket are encapsulated in this class. There are a few calls left out:
The database calls of form getXbyY (for example, gethostbyname), and IP address conversion routines (for example, inet_ntoa()). These are encapsulated by the RWInetHost and RWInetPort classes.
The host - network conversion calls (htons() and friends). These are not needed-the C++ API does the conversions for you automatically.
select(). This is encapsulated by the RWSocketEvent class.
In addition to the functions that match the sockets API, some convenience functions are also provided. These are the functions id(), valid(), socket(), recvAtLeast(), and sendAtLeast().
The socket is not shut down by a destructor. It must be explicitly shut down by calling close(), closesocket(), or shutdown(). Use the RWPortal layer for objects that close the portal automatically using a destructor.
The socket portal provided by RWSocket has no state. All state (whether the socket blocks, etc.) is kept in the communications channel.
In many cases, Tools.h++ Professional provides a C++ wrapper for the native socket API. As a result, return values from socket API calls are returned to the caller unaltered.
NOTE: This can result in different return values, and in some cases different behavior, between calls to the same Tools.h++ Professional member functions on different platforms (BSD platforms vs. Winsock platforms, for instance).
For example, a connect call on a non-blocking socket will return with EINPROGRESS from BSD, but will return with WSAVEWOULDBLOCK from Winsock. As a result, users should consult their implementation-specific users guide to identify expected behavior.
SOCKET
SOCKET is the type used by the underlying implementation as a reference to the communication channel.
RWSocket();
The default constructor sets the socket to an invalid state. You must initialize it with a call to socket(), connect(), bind(), or listen() before it can be used.
RWSocket(const RWSocket&);
Creates another portal into the same communications channel.
RWSocket(const RWSockType& socketType);
Creates an unconnected socket of the specified type. The resulting socket must be bound to an address using bind(), connect(), or listen() before it can be used.
RWSocket(SOCKET existingSocket);
Creates an RWSocket that encapsulates the C socket.
RWSocket(const RWSocket& x);
Creates a copy of x.
RWSocket& operator=(const RWSocket& s);
Sets self to be another portal into the same communications channel as s. The previous value of self is lost.
RWBoolean operator==(const RWSocket& s) const;
Returns TRUE if the two sockets refer to the same underlying communications channel.
RWSocket accept(RWSockAddr *addr =0) const;
Accepts a connection that is waiting at this socket. A queue for incoming connections must first be created using listen(). If addr is non-null, the peer's address is returned in addr. You can also get this information by calling getpeername() on the returned RWSocket.
If the socket is set to block (the default), then accept() blocks until a connection request arrives. If the socket is set to be non-blocking, accept() returns right away. If no connections were available, the returned socket is invalid (use valid() to check) and *addr is unchanged.
void bind(const RWSockAddrBase& address);
Assigns an address to an as-yet unnamed socket. This is used primarily by servers that need to specify the port on which they wait for connections. If the socket has not yet been initialized via socket(), then bind() initializes it.
void close(); void closesocket();
Terminates this connection and removes the socket. The socket is set to an invalid state. Unless this socket is being shared with another process, the resources used to maintain the socket are deallocated and any unread data is discarded.
close() and closesocket() are synonyms. Usually, Unix people use close() and Winsock people use closesocket().
void connect(const RWSockAddrBase& address);
Connects to a remote socket. If this is a stream socket, connect() performs the initial handshaking with the remote side. If this is a datagram socket, connect() sets up the target for communication, but nothing is sent out over the wire. If the socket has not been initialized with socket(), then connect() initializes it.
RWSockAddr getpeername() const;
Returns the address of the peer connected to this socket.
RWSockAddr getsockname() const;
Returns the address of this socket.
void getsockopt(int level, int option, void *optval, int *optlen) const; int getsockopt(int option) const;
Determines a socket option setting. The second function assumes that you are dealing with the SOL_SOCKET level and that the option value is an integer, which is the usual case.
RWSockType getsocktype() const;
Returns the type information for this socket.
RWCString id(unsigned level=0);
Returns a string describing self. The verbosity of the output is controlled by level with level=0 being the most basic and level=9 the most verbose.
void ioctl(long cmd, void *arg) const; void ioctl(long cmd, int arg) const; int ioctl(long cmd) const; void ioctlsocket(long cmd, void *arg) const; void ioctlsocket(long cmd, int arg) const; int ioctlsocket(long cmd) const;
Get or retrieve socket operating parameters. The versions that return an integer are useful with commands that return ints (like FIONREAD or SIOCATMARK). The versions that take an integer argument are useful with commands that expect an integer argument and return nothing (like FIONBIO). The ioctlsocket() functions are aliases for ioctl().
The ioctl() functions are commonly used to set blocking or non-blocking status on a socket. To set a socket to non-blocking mode, use ioctl(FIONBIO,1). To set it to blocking mode, use ioctl(FIONBIO,0). Alternatively, you can use the macros SET_BLOCKING(RWSocket) and SET_NON_BLOCKING(RWSocket) to set the blocking mode on an RWSocket.
void listen(int backlog=5) const; void listen(const RWSockAddrBase& addr, int backlog=5) const;
Prepares a socket to accept incoming connections. The backlog parameter indicates how many incoming connection requests that the protocol software enqueues while a connection is being processed. If the address is not provided, it must first be set using bind().
RWCString recv(int flags=0) const; int recv(char *buf, int len, int flags=0,RWNetBuf::State* s=0) const;
Receives data from the socket. recv() is used to read data from a connected socket. The flags parameter is formed by ORing one or more of MSG_OOB (out of band data), or MSG_PEEK (peek at data on the socket but don't consume it). The variant that uses an explicit buffer returns the number of bytes actually received. This may be zero in the case of a non-blocking socket with no data waiting.
RWCString recvAtLeast(int n) const; int recvAtLeast(char *buf, int len, int n) const;
This is guaranteed to either receive n characters or throw an exception. The call is only valid for stream sockets. The implementation loops over recv until all of the data has been sent. An exception is thrown if one of the calls to recv returns no data. Calling recvAtLeast on a non-blocking socket is therefore likely to cause an exception.
RWCString recvfrom(RWSockAddr *addr=0, int flags=0) const; int recvfrom(char *buf, int len, RWSockAddr *addr=0, int flags=0) const; int recvmsg(msghdr *msg, int flags=0) const;
Receives data from the socket. recvfrom() and recvmsg() can be used on any socket. The flags parameter is formed by ORing one or more of MSG_OOB (out of band data) or MSG_PEEK (peek at data on the socket but don't consume it). addr, if it is specified and if the socket is a datagram socket, becomes the address of the originator of the message. The variant that uses an explicit buffer returns the number of bytes actually received. This may be zero in the case of a non-blocking socket with no data waiting.
int send(const RWCString& buf, int flags=0) const; int send(const char *buf, int len, int flags=0) const;
Sends data out a socket. send() is used to send data from a connected socket. These functions return the number of bytes sent.
Note, when using send(), it is the responsibility of the application to check the number of bytes sent, and resend if necessary. The sendatleast() method guarantees the transmission of the number of bytes specified (or the entire buffer if no size is specified).
void sendAtLeast(const RWCString& buf) const; int sendAtLeast(const RWCString& buf, int n) const; void sendAtLeast(const char* buf, int len) const; int sendAtLeast(const char* buf, int len, int n) const;
This is guaranteed to send at least n characters or the entire buffer if no n is specified. This call is only valid for stream sockets. The implementation loops over send() to send the data. If any of the calls to send cannot send any data, an exception is thrown. Calling sendAtLeast() on a non-blocking socket usually causes an exception if n is greater than the amount of unused space in the system's buffer for the socket.
int sendto(const RWCString& buf, const RWSockAddrBase& to, int flags=0) const; int sendto(const char *buf, int len, const RWSockAddrBase& to, int flags=0) const; int sendmsg(msghdr *msg, int flags=0) const;
Sends data out a socket. sendto() and sendmsg() can be used on any socket. The to parameter is ignored for a connected socket. These functions return the number of bytes sent. This is zero if the socket is non-blocking and the internal buffer for the socket is full.
void setsockopt(int level, int option, void *optval, int optlen) const; void setsockopt(int option, int optval) const;
Sets a socket option setting. The second function assumes that you are dealing with the SOL_SOCKET level and that the option value is an integer, which is the usual case.
void shutdown(int how=2) const;
Shuts down either the reading side (how=0), the writing side (how=1), or both sides (how=2) of a full duplex connection. The socket resources are not deallocated. Use close() or closesocket() for that.
void shutdownread() const; void shutdownwrite() const;
Shuts down one side of the connection.
SOCKET socket() const;
Returns the C API socket descriptor encapsulated in RWSocket.
void socket(const RWSockType& type);
Creates an unconnected socket of the specified type. The resulting socket must be bound to an address using bind(), connect(), or listen() before it can be used. If self was already associated with a socket, that association is lost.
RWBoolean valid() const;
Checks if the socket is ready for use.
SOCKET socket_;
Contains the socket itself. No other state is stored in this class. All state information related to the socket is kept in the socket.
void clearError() const;
Sets the error code to no error. Using this function, rather than the underlying OS specific function calls, provides portability.
static void doRaise(int err, const char *funcName);
Throws an exception based on the last error.
int lastError() const;
Returns the last error that happened on this socket. Using this function, rather than the underlying OS specific function calls, provides portability.
void raise(const char *funcName) const; void raiseUnlessWouldBlock(const char *funcName) const;
Throws an exception based on the last error. The function raiseUnlessWouldBlock returns instead of throwing an exception if this socket is a non-blocking socket that wants to block.
All exceptions thrown in the RWSocket implementation are thrown via these calls. In the end, doRaise() always does the work. This means error handling policies can be changed by reimplementing doRaise(). In a future release, a user definable error handler may be dropped in here. Note that we cannot just make these functions virtual. This is a concrete class, and virtual functions and concrete classes don't mix, because the virtual definitions would get lost when the object was sliced.
ostream& operator<<(ostream& strm, const RWSocket& x);
Outputs a representation of x on strm. The representation is generated using the member function x.id() with level=0.
Note: This class does not have an extraction (>>) operator.
The following macros provide a convenient way to set the blocking mode on an RWSocket.
SET_BLOCKING(RWSocket)
Sets an RWSocket into blocking mode.
SET_NON_BLOCKING(RWSocket)
Sets an RWSocket into non-blocking mode.
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.