TcpServer.cc revision 65c497a3
165c497a3SShuo Chen// excerpts from http://code.google.com/p/muduo/ 265c497a3SShuo Chen// 365c497a3SShuo Chen// Use of this source code is governed by a BSD-style license 465c497a3SShuo Chen// that can be found in the License file. 565c497a3SShuo Chen// 665c497a3SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 765c497a3SShuo Chen 865c497a3SShuo Chen#include "TcpServer.h" 965c497a3SShuo Chen 1065c497a3SShuo Chen#include "logging/Logging.h" 1165c497a3SShuo Chen#include "Acceptor.h" 1265c497a3SShuo Chen#include "EventLoop.h" 1365c497a3SShuo Chen#include "SocketsOps.h" 1465c497a3SShuo Chen 1565c497a3SShuo Chen#include <boost/bind.hpp> 1665c497a3SShuo Chen 1765c497a3SShuo Chen#include <stdio.h> // snprintf 1865c497a3SShuo Chen 1965c497a3SShuo Chenusing namespace muduo; 2065c497a3SShuo Chen 2165c497a3SShuo ChenTcpServer::TcpServer(EventLoop* loop, const InetAddress& listenAddr) 2265c497a3SShuo Chen : loop_(CHECK_NOTNULL(loop)), 2365c497a3SShuo Chen name_(listenAddr.toHostPort()), 2465c497a3SShuo Chen acceptor_(new Acceptor(loop, listenAddr)), 2565c497a3SShuo Chen started_(false), 2665c497a3SShuo Chen nextConnId_(1) 2765c497a3SShuo Chen{ 2865c497a3SShuo Chen acceptor_->setNewConnectionCallback( 2965c497a3SShuo Chen boost::bind(&TcpServer::newConnection, this, _1, _2)); 3065c497a3SShuo Chen} 3165c497a3SShuo Chen 3265c497a3SShuo ChenTcpServer::~TcpServer() 3365c497a3SShuo Chen{ 3465c497a3SShuo Chen} 3565c497a3SShuo Chen 3665c497a3SShuo Chenvoid TcpServer::start() 3765c497a3SShuo Chen{ 3865c497a3SShuo Chen if (!started_) 3965c497a3SShuo Chen { 4065c497a3SShuo Chen started_ = true; 4165c497a3SShuo Chen } 4265c497a3SShuo Chen 4365c497a3SShuo Chen if (!acceptor_->listenning()) 4465c497a3SShuo Chen { 4565c497a3SShuo Chen loop_->runInLoop( 4665c497a3SShuo Chen boost::bind(&Acceptor::listen, get_pointer(acceptor_))); 4765c497a3SShuo Chen } 4865c497a3SShuo Chen} 4965c497a3SShuo Chen 5065c497a3SShuo Chenvoid TcpServer::newConnection(int sockfd, const InetAddress& peerAddr) 5165c497a3SShuo Chen{ 5265c497a3SShuo Chen loop_->assertInLoopThread(); 5365c497a3SShuo Chen char buf[32]; 5465c497a3SShuo Chen snprintf(buf, sizeof buf, "#%d", nextConnId_); 5565c497a3SShuo Chen ++nextConnId_; 5665c497a3SShuo Chen std::string connName = name_ + buf; 5765c497a3SShuo Chen 5865c497a3SShuo Chen LOG_INFO << "TcpServer::newConnection [" << name_ 5965c497a3SShuo Chen << "] - new connection [" << connName 6065c497a3SShuo Chen << "] from " << peerAddr.toHostPort(); 6165c497a3SShuo Chen InetAddress localAddr(sockets::getLocalAddr(sockfd)); 6265c497a3SShuo Chen // FIXME poll with zero timeout to double confirm the new connection 6365c497a3SShuo Chen TcpConnectionPtr conn( 6465c497a3SShuo Chen new TcpConnection(loop_, connName, sockfd, localAddr, peerAddr)); 6565c497a3SShuo Chen connections_[connName] = conn; 6665c497a3SShuo Chen conn->setConnectionCallback(connectionCallback_); 6765c497a3SShuo Chen conn->setMessageCallback(messageCallback_); 6865c497a3SShuo Chen conn->setCloseCallback( 6965c497a3SShuo Chen boost::bind(&TcpServer::removeConnection, this, _1)); 7065c497a3SShuo Chen conn->connectEstablished(); 7165c497a3SShuo Chen} 7265c497a3SShuo Chen 7365c497a3SShuo Chenvoid TcpServer::removeConnection(const TcpConnectionPtr& conn) 7465c497a3SShuo Chen{ 7565c497a3SShuo Chen loop_->assertInLoopThread(); 7665c497a3SShuo Chen LOG_INFO << "TcpServer::removeConnection [" << name_ 7765c497a3SShuo Chen << "] - connection " << conn->name(); 7865c497a3SShuo Chen size_t n = connections_.erase(conn->name()); 7965c497a3SShuo Chen assert(n == 1); (void)n; 8065c497a3SShuo Chen loop_->queueInLoop( 8165c497a3SShuo Chen boost::bind(&TcpConnection::connectDestroyed, conn)); 8265c497a3SShuo Chen} 8365c497a3SShuo Chen 84