前文
一般是由客户端主动发起连接,而主动发起连接就比被动接受连接要复杂一些,一方面是错误处理麻烦,另一方面是要考虑重试。发起连接的基本方式是调用connect,当socket变得可写时,表明连接建立完毕,但其中要处理各种错误,要判断连接是否建立成功。
因此,实现中我们将其封装为Connector类,将其作为TCP客户端TcpClient类的成员,需要注意的几个地方是:
- 用于建立连接的socket是一次性的,一旦出错,就无法恢复,只能关闭重来。但Connector是可以反复使用的,因此每次尝试连接都要使用新的socket和新的channel。
- 错误代码与accept不同,EAGAIN是真的错误,表明本机的临时端口号暂时用完,要关闭socket再延期重试。
- 即便出现socket可写,也不一定意味着连接已成功建立,还需要用
getsockopt
再次确认一下。 - 重试的间隔应该逐渐延长,例如0.5s、1s、2s、4s,直至30s。
- 要处理自连接,处理的办法是断开连接再重试
Connector类
connector的构造函数为:
Connector(EventLoop* loop, const InetAddress& serverAddr);
其核心成员函数为
void start();
void startInLoop();
void connect();
void connecting(int sockfd);
void handleWrite();
voi