您的位置:首页 > 其它

sockutil工具类

2014-01-08 23:38 225 查看
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__
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: