TCP Server实现
一
TCP server用于管理Acceptor类接受的TCP连接
TCP Server接受连接时的时序图
二
muduo处理TcpConnection类的关闭采用的是被动关闭,即对方关闭连接,本地read(2)系统调用返回0,触发关闭逻辑,连接关闭的时序图如下
当TcpConnection从TcpServer中erase()后,如果用户不持有该TcpConnection对象的shared_ptr指针,则其引用计数为1(因为Poller类持有的Channel还有该TcpConnection对象的week_ptr指针,在调用Channel::handleEvent()方法时,会将week_ptr提升为shared_ptr,故引用计数为1)
以下与TcpConnection相关
三
读取数据时,将数据存放在Buffer类中,缓冲区初始化大小为8+1024字节;通过Buffer::readfd()方法将socketfd中的数据读取到缓冲区,如果初始缓冲区大小不够,该方法会先将数据读取的栈上的char extrabuf[65536]数组中,该数组保证了千兆网(1Gbps)满载时500us的数据输入量( 2 30 / 8 / 2000 ≈ 2 16 2^{30}/8/2000 ≈ 2^{16} 230/8/2000≈216),因此通常只需调用一次readv(2)。
ssize_t Buffer::readFd(int fd, int* savedErrno)
{
// saved an ioctl()/FIONREAD call to tell how much to read
char extrabuf[65536];
struct iovec vec[2];
const size_t writable = writableBytes();
vec[0].iov_base = begin()+writerIndex_;
vec[0].iov_len = writable;
vec[1].iov_base = extrabuf;
vec[1].iov_len = sizeof extrabuf;
// when there is enough space in this buffer, don't read into extrabuf.
// when extrabuf is used, we read 128k-1 bytes at most.
const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1;
const ssize_t n = sockets::readv(fd, vec, iovcnt);
if (n < 0)
{
*savedErrno = errno;
}
else if (implicit_cast<size_t>(n) <= writable)
{
writerIndex_ += n;
}
else