TcpConnection类
- TcpConnection用来表示一个 TCP 连接, 不可再生, 如果这个连接断开, 那么该TcpConnection就失去了意义。
- TcpConnection相当于是对服务器和客户端之间连接的一种抽象。
- 类中主要是EventLoop、Socket以及Channel这三个类对象指针,其中第一个用于指向当前连接所属的事件循环,而 Socket用来指明用于网络通信的cfd,Channel表示本次连接的通道,用来封装cfd的各种行为,在TcpConnection这个类构造的时候,便会将对应的读写回调处理函数注册进Channel中。
- TcpConnection中包含有封装好的读写 buffer, 用来收发数据
- TcpConnection的生命周期由智能指针shared_ptr来管理, 具体在下面的注释中有
数据成员:
enum StateE:枚举类型,包含TCP连接的状态
EventLoop* loop_:loop_指针指向所属的EventLoop对象
string name_:连接名
StateE state_:连接的状态
boost::scoped_ptr socket_:套接字成员socket_
boost::scoped_ptr channel_:通道成员channel_
InetAddress localAddr_:tcp连接的本地地址
InetAddress peerAddr_:tcp连接的对等方地址
ConnectionCallback connectionCallback_:连接到来的回调函数connectionCallback_,由TcpServer::newConnection()函数设置
MessageCallback messageCallback_:消息到来的回调函数messageCallback_,由TcpServer::newConnection()函数设置
WriteCompleteCallback writeCompleteCallback_:数据发送完毕时的回调函数,即所有的用户数据都已拷贝到内核缓冲区时回调该函数,outputBuffer_被清空也会回调该函数,可以理解为低水位标回调函数
HighWaterMarkCallback highWaterMarkCallback_:高水位标回调函数
CloseCallback closeCallback_:连接断开时的回调函数closeCallback_
size_t highWaterMark_:高水位标
Buffer inputBuffer_:应用层接收缓冲区
Buffer outputBuffer_:应用层发送缓冲区
boost::any context_:绑定一个未知类型的上下文对象
typedef
typedef boost::shared_ptr TcpConnectionPtr
成员函数:
TcpConnection(EventLoop* loop,const string& name,int sockfd,const InetAddress& localAddr,const InetAddress& peerAddr):构造函数
~TcpConnection():析构函数
EventLoop* getLoop() const:返回所属EventLoop
const string& name() const:返回连接的连接名
const InetAddress& localAddress():返回tcp连接的本地地址
const InetAddress& peerAddress():返回tcp连接的对等方地址
bool connected() const:判断当前tcp连接是否已经连接
void send(const void* message, size_t len):发送长度为len的message
void send(const StringPiece& message):发送一个StringPiece类型的message
void send(Buffer* message):发送一个Buffer类型的message
void shutdown():关闭连接写的这一半
void setTcpNoDelay(bool on):禁用Nagle算法,可以避免连续发包出现延迟
void setConnectionCallback(const ConnectionCallback& cb):设置连接到来或者连接关闭回调函数
void setMessageCallback(const MessageCallback& cb):设置消息到来回调函数
Buffer* inputBuffer():返回应用层接收缓冲区inputBuffer_
void setWriteCompleteCallback(const WriteCompleteCallback& cb):设置数据发送完毕时的回调函数
void setHighWaterMarkCallback(const HighWaterMarkCallback& cb, size_t highWaterMark):设置高水位标回调函数
Buffer* inputBuffer():返回应用层接收缓冲区inputBuffer_
void setCloseCallback(const CloseCallback& cb):设置连接断开回调函数
void connectEstablished():当新连接建立时调用该函数
void connectDestroyed():当连接断开时调用的函数
void handleRead(Timestamp receiveTime):通道可读事件到来的时候,回调的函数
void handleClose():通道关闭事件到来的时候,回调的函数
void handleError():通道出现错误事件的时候,回调的函数
void sendInLoop(const StringPiece& message):被send()调用,用来发送数据
void sendInLoop(const void* message, size_t len):被send()调用,用来发送数据
void shutdownInLoop():被shutdown()调用,关闭连接写的这一半
void setState(StateE s):设置连接的状态
TcpConnection.h
// This is a public header file, it must only include public header files.
#ifndef MUDUO_NET_TCPCONNECTION_H
#define MUDUO_NET_TCPCONNECTION_H
#include <muduo/base/Mutex.h>
#include <muduo/base/StringPiece.h>
#include <muduo/base/Types.h>
#include <muduo/net/Callbacks.h>
//#include <muduo/net/Buffer.h>
#include <muduo/net/InetAddress.h>
//#include <boost/any.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
namespace muduo
{
namespace net
{
class Channel;
class EventLoop;
class Socket;
///
/// TCP connection, for both client and server usage.
///
/// This is an interface class, so don't expose too much details.
class TcpConnection : boost::noncopyable,
public boost::enable_shared_from_this<TcpConnection>
{
public:
/// Constructs a TcpConnection with a connected sockfd
///
/// User should not create this object.
TcpConnection(EventLoop* loop,
const string& name,
int sockfd,
const InetAddress& localAddr,
const InetAddress& peerAddr);
~TcpConnection();
EventLoop* getLoop() const { return loop_; }
const string& name() const { return name_; }
const InetAddress& localAddress() { return localAddr_; }
const InetAddress& peerAddress() { return peerAddr_; }
bool connected() const { return state_ == kConnected; }
void setConnectionCallback(const ConnectionCallback& cb)
{ connectionCallback_ = cb; }
void setMessageCallback(const MessageCallback& cb)
{ messageCallback_ = cb; }
/// Internal use only.
//设置连接断开回调函数
void setCloseCallback(const CloseCallback& cb)
{ closeCallback_ = cb; }
// called when TcpServer accepts a new connection
void connectEstablished(); // should be called only once
// called when TcpServer has removed me from its map
//连接断开时调用的函数
void connectDestroyed(); // should be called only once
private:
enum StateE { kDisconnected, kConnecting, kConnected, kDisconnecting };
void handleRead(Timestamp receiveTime);
//通道关闭事件到来的时候,回调的函数
void handleClose();
//通道出现错误事件的时候,回调的函数
void handleError();
void setState(StateE s) { state_ = s; }
EventLoop* loop_; // 所属EventLoop
string name_; // 连接名
StateE state_; // FIXME: use atomic variable
// we don't expose those classes to client.
boost::scoped_ptr<Socket> socket_;
boost::scoped_ptr<Channel> channel_;
InetAddress localAddr_;
InetAddress peerAddr_;
ConnectionCallback connectionCallback_;
MessageCallback messageCallback_;
//连接断开时的回调函数
CloseCallback closeCallback_;
};
typedef boost::shared_ptr<TcpConnection> TcpConnectionPtr;
}
}
#endif // MUDUO_NET_TCPCONNECTION_H
TcpConnection.cc
#include <muduo/net/TcpConnection.h>
#include <muduo/base/Logging.h>
#include <muduo/net/Channel.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/Socket.h>
#include <muduo/net/SocketsOps.h>
#include <boost/bind.hpp>
#include <errno.h>
#include <stdio.h>
using namespace muduo;
using namespace muduo::net;
/*
void muduo::net::defaultConnectionCallback(const TcpConnectionPtr& conn)
{
LOG_TRACE << conn->localAddress().toIpPort() << " -> "
<< conn->peerAddress().toIpPort() << " is "
<< (conn->connected() ? "UP" : "DOWN");
}
void muduo::net::defaultMessageCallback(const TcpConnectionPtr&,
Buffer* buf,
Timestamp)
{
buf->retrieveAll();
}
*/
TcpConnection::TcpConnection(EventLoop* loop,
const string& nameArg,
int sockfd,
const InetAddress& localAddr,
const InetAddress& peerAddr)
: loop_(CHECK_NOTNULL(loop)),
name_(nameArg),
state_(kConnecting),
socket_(new Socket(sockfd)),
channel_(new Channel(loop, sockfd)),
localAddr_(localAddr),
peerAddr_(peerAddr)/*,
highWaterMark_(64*1024*1024)*/
{
// 通道可读事件到来的时候,回调TcpConnection::handleRead,_1是事件发生时间
channel_->setReadCallback(
boost::bind(&TcpConnection::handleRead, this, _1));
LOG_DEBUG << "TcpConnection::ctor[" << name_ << "] at " << this
<< " fd=" << sockfd;
socket_->setKeepAlive(true);
}
TcpConnection::~TcpConnection()
{
LOG_DEBUG << "TcpConnection::dtor[" << name_ << "] at " << this
<< " fd=" << channel_->fd();
}
void TcpConnection::connectEstablished()
{
loop_->assertInLoopThread();
assert(state_ == kConnecting);
setState(kConnected);
channel_->tie(shared_from_this());
// TcpConnection所对应的通道加入到Poller关注
channel_->enableReading();
connectionCallback_(shared_from_this());
}
void TcpConnection::handleRead(Timestamp receiveTime)
{
/*
loop_->assertInLoopThread();
int savedErrno = 0;
ssize_t n = inputBuffer_.readFd(channel_->fd(), &savedErrno);
if (n > 0)
{
messageCallback_(shared_from_this(), &inputBuffer_, receiveTime);
}
else if (n == 0)
{
handleClose();
}
else
{
errno = savedErrno;
LOG_SYSERR << "TcpConnection::handleRead";
handleError();
}
*/
loop_->assertInLoopThread();
char buf[65536];
ssize_t n = ::read(channel_->fd(), buf, sizeof buf);
//MessageCallback定义在Callbacks.h中
messageCallback_(shared_from_this(), buf, n);
}
}