c++ poco StreamSocket 源码剖析

1.概述

  “This class provides an interface to a TCP stream socket.”,StreamSocket类是Socket类的子类,用作TCP客户端。本篇系统环境为linux,欢迎交流和指出问题,转载请标明作者和链接地址http://blog.csdn.net/lz_obj/article/details/75825413

2.类图

这里写图片描述
关系说明:
  StreamSocket类公有继承于Socket类。Socket类拥有私有成员(SocketImpl*)_pImpl。SocketImpl类是StreamSocketImpl类的父类,Socket类的构造函数将new子类StreamSocketImpl的堆地址赋值给Socket的私有数据成员_pImpl,Socket类在接口实现上调用了SocketImpl类和StreamSocketImpl类的方法。总之,StreamSocket类接口对于linux系统调用的运用,本质实现于Socket、SocketImpl、StreamSocketImpl等类。

3.接口解析

3.1构造函数
StreamSocket::StreamSocket(): Socket(new StreamSocketImpl)
{
}

StreamSocket构造函数调用父类Socket的构造函数Socket(SocketImpl* pImpl);

Socket::Socket(SocketImpl* pImpl): _pImpl(pImpl)
{
    poco_check_ptr(_pImpl);
}

(SocketImpl*)_pImpl是Socket类的私有成员,SocketImpl类是StreamSocketImpl类的父类,这里用到了“工厂模式”。

SocketImpl::SocketImpl():_sockfd(POCO_INVALID_SOCKET),_blocking(true)
{
}
StreamSocketImpl::StreamSocketImpl()
{
}

父类SocketImpl构造函数对成员_sockfd和_blocking进行初始化,子类StreamSocketImpl构造函数未进行操作。SocketImpl类私有成员_sockfd、_blocking声明如下:poco_socket_t _sockfd;bool _blocking。”poco_socket_t”是int数据类型的宏,_sockfd代表socket描述符,_blocking代表是否阻塞。前者被初始化为POCO_INVALID_SOCKET非法socketfd,后者被初始化为true阻塞态。

3.2析构函数
StreamSocket::~StreamSocket()
{
}
Socket::~Socket()
{
    _pImpl->release();
}

SocketImpl类是RefCountedObject类的子类,release()是RefCountedObject类的方法。

inline void RefCountedObject::release() const throw()
{
    try
    {
        if (--_counter == 0) delete this;
    }
    catch (...)
    {
        poco_unexpected();
    }
}

“delete this”用于释放StreamSocket类运行构造函数时,SocketImpl* pImpl = new StreamSocketImpl操作所动态分配的空间。

3.3connect连接函数
void StreamSocket::connect(const SocketAddress& address)
{
    impl()->connect(address);
}
void SocketImpl::connect(const SocketAddress& address)
{
    if (_sockfd == POCO_INVALID_SOCKET)
    {
        init(address.af());
    }
    int rc;
    do
    {
#if defined(POCO_VXWORKS)
        rc = ::connect(_sockfd, (sockaddr*) address.addr(), address.length());
#else
        rc = ::connect(_sockfd, address.addr(), address.length());
#endif
    }
    while (rc != 0 && lastError() == POCO_EINTR);
    if (rc != 0) 
    {
        int err = lastError();
        error(err, address.toString());
    }
}
void SocketImpl::init(int af)
{
    initSocket(af, SOCK_STREAM);
}
void SocketImpl::initSocket(int af, int type, int proto)
{
    poco_assert (_sockfd == POCO_INVALID_SOCKET);

    _sockfd = ::socket(af, type, proto);
    if (_sockfd == POCO_INVALID_SOCKET)
        error();

#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
    setOption(SOL_SOCKET, SO_NOSIGPIPE, 1);
#endif
}

connect完成系统调用和操作:
1)判断socket描述符是否是

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值