1、sockdef.h
#if (_MSC_VER >= 1020)
#pragma once
#endif
#ifndef __SOCKDEF_H__
#define __SOCKDEF_H__
#ifdef WINVER
/**
* Windows socket 2 header file.
*/
#include <assert.h>
#include <winsock2.h>
#else
/**
* Linux socket header files.
*/
#include "platform.h"
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
/**
* The socket handle
*/
typedef int SOCKET;
/**
* Invalid socket value.
*/
#define INVALID_SOCKET (-1)
/**
* Socket error.
*/
#define SOCKET_ERROR (-1)
#endif // WINVER
#endif // __SOCKDEF_H__
2、sockutil.h
#if (_MSC_VER >= 1020)
#pragma once
#endif
#ifndef __SOCKUTIL_H__
#define __SOCKUTIL_H__
#include "sockdef.h"
///
// Classes in this file:
//
// _sockaddr_t
// _socket_t
// _hostent_t
// _addrinfo_t
namespace stdutil {
///
// Interface of the _sockaddr_t class
//
class _sockaddr_t : public sockaddr_in
{
// Constructors
public:
_sockaddr_t();
_sockaddr_t(u_long addr, u_short port);
_sockaddr_t(in_addr addr, u_short port);
_sockaddr_t(const char* addr, u_short port);
// Operations
public:
operator sockaddr*();
operator const sockaddr*() const;
void set(u_long addr, u_short port);
void set(in_addr addr, u_short port);
void set(const char* addr, u_short port);
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif
};
///
// Interface of the _socket_t class
//
class _socket_t
{
// Constructors/Destructor
public:
_socket_t();
~_socket_t();
// Operations
public:
bool create(int af = AF_INET, int type = SOCK_STREAM, int protocol = IPPROTO_TCP);
void close();
operator SOCKET() const;
SOCKET detach();
void attach(SOCKET sock);
SOCKET accept(sockaddr* addr = NULL, int* addrlen = NULL) const;
bool accept(_socket_t& client, sockaddr* addr = NULL, int* addrlen = NULL) const;
int listen(int backlog = 10) const;
int shutdown(int how) const;
#ifdef WINVER
int ioctl(long cmd, u_long* param) const;
#endif
int bind(const sockaddr* addr, int addrlen = sizeof(sockaddr_in)) const;
int bind(const char* addr, u_short port) const;
int connect(const sockaddr* addr, int addrlen = sizeof(sockaddr_in)) const;
int connect(const char* addr, u_short port) const;
int send(const void* buf, int size, int flags = 0) const;
int recv(void* buf, int size, int flags = 0) const;
int sendto(const void* buf, int size, const sockaddr* to, int tolen = sizeof(sockaddr_in), int flags = 0) const;
int sendto(const void* buf, int size, const char* to, u_short port, int flags = 0) const;
int recvfrom(void* buf, int size, sockaddr* from = NULL, int* fromlen = NULL, int flags = 0) const;
// Attributes
public:
bool empty() const;
int getsockname(sockaddr* name, int& namelen) const;
int getpeername(sockaddr* name, int& namelen) const;
template <typename _Ty>
int getsockopt(int optname, _Ty& value, int level = SOL_SOCKET) const;
template <typename _Ty>
int setsockopt(int optname, const _Ty& value, int level = SOL_SOCKET) const;
// Implementation
private:
_socket_t(const _socket_t& that);
_socket_t& operator=(const _socket_t& that);
// Data members
public:
SOCKET _Socket;
};
///
// Interface of the _hostent_t class
//
class _hostent_t
{
// Constructors
public:
_hostent_t();
// Operations
public:
hostent* get(const char* name = NULL);
in_addr* addr(size_t index) const;
const char* alias(size_t index) const;
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif
// Attributes
public:
bool empty() const;
// Data members
public:
hostent* host;
};
///
// Interface of the _addrinfo_t class
//
class _addrinfo_t : public addrinfo
{
// Constructors/Destructor
public:
explicit _addrinfo_t(int family = AF_UNSPEC, int socktype = SOCK_STREAM, int protocol = IPPROTO_TCP);
~_addrinfo_t();
// Operations
public:
bool get(const char* hostname, const char* servicename = "80");
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr> void Dump(const _Pr& _Printer) const;
#endif
// Attributes
public:
bool empty() const;
// Implementation
private:
_addrinfo_t(const _addrinfo_t& that);
_addrinfo_t& operator=(const _addrinfo_t& that);
// Data members
public:
addrinfo* ai_list;
};
} // namespace stdutil
#include "sockutil.inl"
#endif // __SOCKUTIL_H__
3、sockutil.inl
#if (_MSC_VER >= 1020)
#pragma once
#endif
#ifndef __SOCKUTIL_INL__
#define __SOCKUTIL_INL__
#ifndef __SOCKUTIL_H__
#error sockutil.inl requires sockutil.h to be included first
#endif
namespace stdutil {
///
// Implementation of the _sockaddr_t class
//
inline _sockaddr_t::_sockaddr_t()
{
}
inline _sockaddr_t::_sockaddr_t(u_long addr, u_short port)
{
set(addr, port);
sin_family = AF_INET;
}
inline _sockaddr_t::_sockaddr_t(in_addr addr, u_short port)
{
set(addr, port);
sin_family = AF_INET;
}
inline _sockaddr_t::_sockaddr_t(const char* addr, u_short port)
{
assert(addr);
set(addr, port);
sin_family = AF_INET;
}
inline _sockaddr_t::operator sockaddr*()
{
return reinterpret_cast<sockaddr*>(this);
}
inline _sockaddr_t::operator const sockaddr*() const
{
return reinterpret_cast<const sockaddr*>(this);
}
inline void _sockaddr_t::set(u_long addr, u_short port)
{
sin_addr.s_addr = addr;
sin_port = port;
}
inline void _sockaddr_t::set(in_addr addr, u_short port)
{
sin_addr = addr;
sin_port = htons(port);
}
inline void _sockaddr_t::set(const char* addr, u_short port)
{
assert(addr);
sin_addr.s_addr = inet_addr(addr);
sin_port = htons(port);
}
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void _sockaddr_t::Dump(const _Pr& _Printer) const
{
_Printer("[ address = %s : %u ]\n", inet_ntoa(sin_addr), ntohs(sin_port));
}
#endif // _CRT_DEBUG_DUMP
///
// Implementation of the _socket_t class
//
inline _socket_t::_socket_t()
: _Socket(INVALID_SOCKET)
{
}
inline _socket_t::~_socket_t()
{
close();
}
inline bool _socket_t::create(int af/* = AF_INET*/, int type/* = SOCK_STREAM*/, int protocol/* = IPPROTO_TCP*/)
{
assert(empty());
return ((_Socket = ::socket(af, type, protocol)) != INVALID_SOCKET);
}
inline void _socket_t::close()
{
#ifdef WINVER
if (_Socket != INVALID_SOCKET && ::closesocket(_Socket) == 0)
_Socket = INVALID_SOCKET;
#else
if (_Socket != INVALID_SOCKET && ::close(_Socket) == 0)
_Socket = INVALID_SOCKET;
#endif // WINVER
}
inline _socket_t::operator SOCKET() const
{
return _Socket;
}
inline SOCKET _socket_t::detach()
{
SOCKET sock = _Socket;
_Socket = INVALID_SOCKET;
return sock;
}
inline void _socket_t::attach(SOCKET sock)
{
close();
_Socket = sock;
}
inline SOCKET _socket_t::accept(sockaddr* addr/* = NULL*/, int* addrlen/* = NULL*/) const
{
assert(!empty());
return ::accept(_Socket, addr, addrlen);
}
inline bool _socket_t::accept(_socket_t& client, sockaddr* addr/* = NULL*/, int* addrlen/* = NULL*/) const
{
assert(!empty());
client.attach(::accept(_Socket, addr, addrlen));
return (client._Socket != INVALID_SOCKET);
}
inline int _socket_t::listen(int backlog/* = 10*/) const
{
assert(!empty());
return ::listen(_Socket, backlog);
}
inline int _socket_t::shutdown(int how) const
{
assert(!empty());
return ::shutdown(_Socket, how);
}
#ifdef WINVER
inline int _socket_t::ioctl(long cmd, u_long* param) const
{
assert(param);
assert(!empty());
return ::ioctlsocket(_Socket, cmd, param);
}
#endif // WINVER
inline int _socket_t::bind(const sockaddr* addr, int addrlen/* = sizeof(sockaddr_in)*/) const
{
assert(addr);
assert(!empty());
return ::bind(_Socket, addr, addrlen);
}
inline int _socket_t::bind(const char* addr, u_short port) const
{
assert(addr);
assert(!empty());
return ::bind(_Socket, _sockaddr_t(addr, port), sizeof(_sockaddr_t));
}
inline int _socket_t::connect(const sockaddr* addr, int addrlen/* = sizeof(sockaddr_in)*/) const
{
assert(addr);
assert(!empty());
return ::connect(_Socket, addr, addrlen);
}
inline int _socket_t::connect(const char* addr, u_short port) const
{
assert(addr);
assert(!empty());
return ::connect(_Socket, _sockaddr_t(addr, port), sizeof(_sockaddr_t));
}
inline int _socket_t::send(const void* buf, int size, int flags/* = 0*/) const
{
assert(buf);
assert(!empty());
return ::send(_Socket, (const char*)buf, size, flags);
}
inline int _socket_t::recv(void* buf, int size, int flags/* = 0*/) const
{
assert(buf);
assert(!empty());
return ::recv(_Socket, (char*)buf, size, flags);
}
inline int _socket_t::sendto(const void* buf, int size, const sockaddr* to, int tolen/* = sizeof(sockaddr_in)*/, int flags/* = 0*/) const
{
assert(to);
assert(buf);
assert(!empty());
return ::sendto(_Socket, (const char*)buf, size, flags, to, tolen);
}
inline int _socket_t::sendto(const void* buf, int size, const char* to, u_short port, int flags/* = 0*/) const
{
assert(to);
assert(buf);
assert(!empty());
return ::sendto(_Socket, (const char*)buf, size, flags, _sockaddr_t(to, port), sizeof(_sockaddr_t));
}
inline int _socket_t::recvfrom(void* buf, int size, sockaddr* from/* = NULL*/, int* fromlen/* = NULL*/, int flags/* = 0*/) const
{
assert(buf);
assert(!empty());
return ::recvfrom(_Socket, (char*)buf, size, flags, from, fromlen);
}
inline bool _socket_t::empty() const
{
return (_Socket == INVALID_SOCKET);
}
inline int _socket_t::getsockname(sockaddr* name, int& namelen) const
{
assert(name);
assert(!empty());
return ::getsockname(_Socket, name, &namelen);
}
inline int _socket_t::getpeername(sockaddr* name, int& namelen) const
{
assert(name);
assert(!empty());
return ::getpeername(_Socket, name, &namelen);
}
template <typename _Ty>
inline int _socket_t::getsockopt(int optname, _Ty& value, int level/* = SOL_SOCKET*/) const
{
assert(!empty());
int size = sizeof(_Ty);
return ::getsockopt(_Socket, level, optname, (char*)&value, &size);
}
template <typename _Ty>
inline int _socket_t::setsockopt(int optname, const _Ty& value, int level/* = SOL_SOCKET*/) const
{
assert(!empty());
return ::setsockopt(_Socket, level, optname, (const char*)&value, sizeof(_Ty));
}
///
// Implementation of the _hostent_t class
//
inline _hostent_t::_hostent_t()
: host(NULL)
{
}
inline hostent* _hostent_t::get(const char* name/* = NULL*/)
{
return (host = ::gethostbyname(name));
}
inline in_addr* _hostent_t::addr(size_t index) const
{
return (in_addr*)host->h_addr_list[index];
}
inline const char* _hostent_t::alias(size_t index) const
{
assert(!empty());
return host->h_aliases[index];
}
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void _hostent_t::Dump(const _Pr& _Printer) const
{
assert(!empty());
_Printer("[ HOST INFO ]\n[\n name = %s, addr type = %d, addr length = %d\n", host->h_name, host->h_addrtype, host->h_length);
if (const char* aliasname = alias(0))
{
_Printer(" aliases = %s\n", aliasname);
for (size_t i = 1; (aliasname = alias(i)) != NULL; ++i)
_Printer(" %s\n", aliasname);
}
in_addr* address = addr(0);
_Printer(" address = %s\n", ::inet_ntoa(*address));
for (size_t i = 1; (address = addr(i)) != NULL; ++i)
_Printer(" %s\n", ::inet_ntoa(*address));
_Printer("]\n");
}
#endif // _CRT_DEBUG_DUMP
inline bool _hostent_t::empty() const
{
return (host == NULL);
}
///
// Implementation of the _addrinfo_t class
//
inline _addrinfo_t::_addrinfo_t(int family/* = AF_UNSPEC*/, int socktype/* = SOCK_STREAM*/, int protocol/* = IPPROTO_TCP*/)
{
::memset(this, 0, sizeof(_addrinfo_t));
ai_family = family;
ai_socktype = socktype;
ai_protocol = protocol;
}
inline _addrinfo_t::~_addrinfo_t()
{
::freeaddrinfo(ai_list);
}
inline bool _addrinfo_t::get(const char* hostname, const char* servicename/* = "80"*/)
{
assert(empty());
return (::getaddrinfo(hostname, servicename, this, &ai_list) == 0);
}
#ifdef _CRT_DEBUG_DUMP
template <typename _Pr>
inline void _addrinfo_t::Dump(const _Pr& _Printer) const
{
assert(!empty());
_Printer("[ ADDRESS INFO ]\n[\n");
for (addrinfo* info = ai_list; info != NULL; info = info->ai_next)
_Printer(" family = %2d, sock type = %d, protocol = %d, address = %s\n", info->ai_family, info->ai_socktype, info->ai_protocol, ::inet_ntoa(((sockaddr_in*)info->ai_addr)->sin_addr));
_Printer("]\n");
}
#endif // _CRT_DEBUG_DUMP
inline bool _addrinfo_t::empty() const
{
return (ai_list == NULL);
}
} // namespace stdutil
#endif // __SOCKUTIL_INL__