IPerf开源代码中SocketAddr类分析

一 点睛

SocketAddr类定义在lib/SocketAddr.hpp中,实现在lib/SocketAddr.cpp中。

SocketAddr类封装了网络通信中经常用到的地址结构以及在这些结构上进行的操作。

地址解析也是在SocketAddr的成员函数中完成的。

sockaddr用来表示网络地址中的通用数据结构。

sockaddr_in用来表示TCP/IP地址的数据结构。

两个结构可以相互转换,它们表示同一地址。它们在内存中对应的区域是重合的。

二 类定义

// 该成员函数都是对mAddress进行读取或修改的操作
class SocketAddr {
public:
    SocketAddr( const char* inHostname = NULL, unsigned short inPort = 0, bool isIPv6 = false );
    SocketAddr( const struct sockaddr* inAddr, Socklen_t inSize );

    ~SocketAddr();

    void setHostname( const char* inHostname );          // DNS lookup
    void getHostname( char* outHostname, size_t len );   // reverse DNS lookup
    void getHostAddress( char* outAddress, size_t len ); // dotted decimal

    void setPort( unsigned short inPort );
    void setPortAny( void );
    unsigned short getPort( void );

    void setAddressAny( void );

    // return pointer to the struct sockaddr
    struct sockaddr* get_sockaddr( void );

    // return pointer to the struct sockaddr_in (IPv4)
    struct sockaddr_in* get_sockaddr_in( void );

    // return pointer to the struct in_addr
    struct in_addr* get_in_addr( void );
#ifdef IPV6
    // return pointer to the struct in_addr
    struct in6_addr* get_in6_addr( void );
#endif
    // return the sizeof the addess structure (struct sockaddr_in)
    Socklen_t get_sizeof_sockaddr( void );

    bool isMulticast( void );

    bool isIPv6(void) {
        return mIsIPv6;
    };

    static bool are_Equal(sockaddr *first, sockaddr *second);
    static bool Hostare_Equal(sockaddr *first, sockaddr *second);

    static Socklen_t mAddress_size;


protected:
    void zeroAddress( void );
    // iperf_sockaddr实际上是sockaddr_in
    iperf_sockaddr mAddress;
        
    bool mIsIPv6;
};

三 类实现

类的成员函数都是对mAddress进行读取或修改的操作,比较复杂的成员函数是setHostname,它完成了地址解析的过程,删减后的源代码如下

void SocketAddr::setHostname( const char* inHostname ) {

    assert( inHostname != NULL );
    mIsIPv6 = false;
    mAddress.sin_family = AF_INET;
    // inet_pton是一个IP地址转换函数,可以在将IP地址在“点分十进制”和“二进制整数”之间转换
    // 因为在window中 gethostbyname 不理解点分十进制
    int rc = inet_pton( AF_INET, inHostname, (unsigned char*)&(mAddress.sin_addr) );
    if ( rc == 0 ) {
        // gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构的指针。
        struct hostent *hostP = gethostbyname( inHostname );
        if ( hostP == NULL ) {
            /* this is the same as herror() but works on more systems */
            const char* format;
            switch ( h_errno ) {
                case HOST_NOT_FOUND:
                    format = "%s: Unknown host\n";
                    break;
                case NO_ADDRESS:
                    format = "%s: No address associated with name\n";
                    break;
                case NO_RECOVERY:
                    format = "%s: Unknown server error\n";
                    break;
                case TRY_AGAIN:
                    format = "%s: Host name lookup failure\n";
                    break;

                default:
                    format = "%s: Unknown resolver error\n";
                    break;
            }
            fprintf( stderr, format, inHostname );
            exit(1);

            return; // TODO throw
        }

        memcpy(&(mAddress.sin_addr), *(hostP->h_addr_list),
               (hostP->h_length));
    }
#endif
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值