1e54e5389SShuo Chen// excerpts from http://code.google.com/p/muduo/ 2e54e5389SShuo Chen// 3e54e5389SShuo Chen// Use of this source code is governed by a BSD-style license 4e54e5389SShuo Chen// that can be found in the License file. 5e54e5389SShuo Chen// 6e54e5389SShuo Chen// Author: Shuo Chen (chenshuo at chenshuo dot com) 7e54e5389SShuo Chen 8e54e5389SShuo Chen#include "TcpServer.h" 9e54e5389SShuo Chen 10e54e5389SShuo Chen#include "logging/Logging.h" 11e54e5389SShuo Chen#include "Acceptor.h" 12e54e5389SShuo Chen#include "EventLoop.h" 13e54e5389SShuo Chen#include "SocketsOps.h" 14e54e5389SShuo Chen 15e54e5389SShuo Chen#include <boost/bind.hpp> 16e54e5389SShuo Chen 17e54e5389SShuo Chen#include <stdio.h> // snprintf 18e54e5389SShuo Chen 19e54e5389SShuo Chenusing namespace muduo; 20e54e5389SShuo Chen 21e54e5389SShuo ChenTcpServer::TcpServer(EventLoop* loop, const InetAddress& listenAddr) 22e54e5389SShuo Chen : loop_(CHECK_NOTNULL(loop)), 23e54e5389SShuo Chen name_(listenAddr.toHostPort()), 24e54e5389SShuo Chen acceptor_(new Acceptor(loop, listenAddr)), 25e54e5389SShuo Chen started_(false), 26e54e5389SShuo Chen nextConnId_(1) 27e54e5389SShuo Chen{ 28e54e5389SShuo Chen acceptor_->setNewConnectionCallback( 29e54e5389SShuo Chen boost::bind(&TcpServer::newConnection, this, _1, _2)); 30e54e5389SShuo Chen} 31e54e5389SShuo Chen 32e54e5389SShuo ChenTcpServer::~TcpServer() 33e54e5389SShuo Chen{ 34e54e5389SShuo Chen} 35e54e5389SShuo Chen 36e54e5389SShuo Chenvoid TcpServer::start() 37e54e5389SShuo Chen{ 38e54e5389SShuo Chen if (!started_) 39e54e5389SShuo Chen { 40e54e5389SShuo Chen started_ = true; 41e54e5389SShuo Chen } 42e54e5389SShuo Chen 43e54e5389SShuo Chen if (!acceptor_->listenning()) 44e54e5389SShuo Chen { 45e54e5389SShuo Chen loop_->runInLoop( 46e54e5389SShuo Chen boost::bind(&Acceptor::listen, get_pointer(acceptor_))); 47e54e5389SShuo Chen } 48e54e5389SShuo Chen} 49e54e5389SShuo Chen 50e54e5389SShuo Chenvoid TcpServer::newConnection(int sockfd, const InetAddress& peerAddr) 51e54e5389SShuo Chen{ 52e54e5389SShuo Chen loop_->assertInLoopThread(); 53e54e5389SShuo Chen char buf[32]; 54e54e5389SShuo Chen snprintf(buf, sizeof buf, "#%d", nextConnId_); 55e54e5389SShuo Chen ++nextConnId_; 56e54e5389SShuo Chen std::string connName = name_ + buf; 57e54e5389SShuo Chen 58e54e5389SShuo Chen LOG_INFO << "TcpServer::newConnection [" << name_ 59e54e5389SShuo Chen << "] - new connection [" << connName 60e54e5389SShuo Chen << "] from " << peerAddr.toHostPort(); 61e54e5389SShuo Chen InetAddress localAddr(sockets::getLocalAddr(sockfd)); 62e54e5389SShuo Chen // FIXME poll with zero timeout to double confirm the new connection 63e54e5389SShuo Chen TcpConnectionPtr conn( 64e54e5389SShuo Chen new TcpConnection(loop_, connName, sockfd, localAddr, peerAddr)); 65e54e5389SShuo Chen connections_[connName] = conn; 66e54e5389SShuo Chen conn->setConnectionCallback(connectionCallback_); 67e54e5389SShuo Chen conn->setMessageCallback(messageCallback_); 68e54e5389SShuo Chen conn->connectEstablished(); 69e54e5389SShuo Chen} 70e54e5389SShuo Chen 71