sockutil工具类

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__


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值