跳转至

Client

Connector

对应于TcpServer中的Acceptor,这里是用于客户端向服务端发起连接。由于连接建立后会得到一个sockfd,那么就会一样Channel对象来监听对应的事件。

    class Connector : noncopyable,
                      public std::enable_shared_from_this<Connector> 
    {
    private:
        EventLoop*  loop_;
        std::unique_ptr<Channel>  channel_; 

    }
这里的channel_,当 sockets::connect(...) 成功返回后,那么就会触发channel_的可写事件,调用回调函数handleWrite(),在这个回调函数里,主要是处于安全因素考虑对得到的sockfd进行检测,如果确实是成功个服务端建立了正确连接,那么就调用newConnectionCallback_。此外,还需要在handWrite()中取消对于sockfd可写事件的关注,以防止出现busy-loop。 + 状态
+ kConnected:这个只有在connect建立成功,触发handleWrite时才会具有的状态 + kConnecting:在handleWrite之前都是这个状态 + kDisconnected:构造函数初始化即这个状态。在stopInLoop()restart()retry()都会将状态重新设置为此状态。 + 函数 + stop():是将调用了connect()函数但还没建立好链接,即状态为kConnecting的连接请求停止掉,并关闭sockfd。 + restartretrystart():内部都是调用startInLoop(),其内部调用connect()来向服务端发起连接请求。 + retry()是先关闭sockfd,再调用startInLoop + restart()没关闭sockfd,就调用startInLoop

    这个里面主要涉及了端口和ip地址复用情况,在`connect()`直接当作建立正确的情况,此时错误 **`EISCONN`**
    ```cpp
        void Connector::connect() {
            int sockfd = sockets::createNonblockingOrDie(serverAddr_.family());
            int ret = sockets::connect(sockfd, serverAddr_.getSockAddr());
            int savedErrno = (ret == 0) ? 0 : errno;
            switch (savedErrno) {
            case 0:
            case EINPROGRESS:   // 由于socket是非堵塞套接字,而connect又不能立即完成的错误。
            case EINTR:         // 被信号中断
            case EISCONN:       // 已经连接
                connecting(sockfd); // 重新连接
                break;
            }
            ...
        }
    ```