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