Boost logo

Boost :

From: mfdylan (dylan_at_[hidden])
Date: 2001-12-18 21:42:54


--- In boost_at_y..., Rob Tougher <rtougher_at_y...> wrote:
> I've been following the group for a month now, and this is my first
post.
>
> I would like to take a shot at a sockets library for boost, and
have attached a header that
> defines the basics for this library. It may be grossly
oversimplistic, but I've got a lot of free
> time on my hands, and with the correct guidance and prodding I
think I could create something
> worth the trouble.
>
> I have a linux box and win98 machine available to me. Any other
platforms I would need help with.
>
I'm not convinced the way you do I/O makes sense to me. What I'd
actually like to see (and have done myself but haven't "boostified")
is a binary_stream class that uses a streambuf to do raw data I/O,
then you just provide a socketbuf class.
That way you could use a socket for "ascii" streaming (using
istream/ostream) and binary streaming. My binary stream class uses
an XDR compatible format, and supplies insertion and extraction for
the most common std data types (which was all I needed, anyway how
often would you stream a multimap).

You need to supply decent DNS resolving capabilities too -
gethostbyname is one of the ugliest APIs in existence to use and it
only supports one type of DNS request. As a convenience you can roll
it into connect, but often you need to do the resolving separately,
if nothing else in order to provide feedback as to what your software
is doing.

Other "must haves":

* non-blocking sockets (including a decent C++ equivalent of select)

* UDP support. You might as well allow selecting other
domains/protocols/types but with default arguments and overloads 99%
of users should never have to worry about them.

* recv_fully() would be helpful too, I've seen a lot of code fail
because programmers assumed that recv would always receive the full
number of bytes they requested.

* Other options that I still use frequently include setting linger
options, setting timeouts, even setting buffer sizes (althrough
setsockopt). I've never seen a C++ class that made a decent job of
supporting these.

Anyway, there are a zillion socket classes out there and I've never
been happy with any of them. I remember being somewhat disappointed
when I first came across boost and noticed no such thing already
existed.

As far as platform-specific stuff goes, the only problematic cases
between Win32 and POSIX are WSAStartup, errno/WSAGetLastError, error
code names (WSAE.../E...), close()/closesocket() and ioctl
()/ioctlsocket() which can all be solved with a header something like
the one below.

Dylan

#if !defined(SOCKETS_H_INC)
#define SOCKETS_H_INC

#if defined(WIN32)
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#define errnosocket WSAGetLastError()
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EADDRINUSE WSAEADDRINUSE
#define ECONNABORTEDE WSACONNABORTED
#define ECONNRESET WSAECONNRESET
#define ECONNREFUSED WSAECONNREFUSED
#define HOST_NOT_FOUND WSAHOST_NOT_FOUND

#else

#include <unistd.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <errno.h>
#if defined(__sun)
#include <sys/filio.h>
#elif defined(__xlC__)
#include <strings.h>
inline int _getsockname(int s, sockaddr* addr, int* l)
{
        return getsockname(s, addr, (size_t*)l);
}
inline int _getpeername(int s, sockaddr* addr, int* l)
{
        return getpeername(s, addr, (size_t*)l);
}
#define getsockname _getsockname
#define getpeername _getpeername
#endif

#define ioctlsocket ioctl
#define closesocket close
#define errnosocket errno

#ifndef INADDR_NONE
#define INADDR_NONE ((in_addr_t)-1)
#endif

#endif

#endif // !defined(SOCKETS_H_INC)


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk