最近在看陈硕老师的《Linux多线程服务端编程:使用muduo C++网络库》,里面用到的muduo代码量不是特别多,很适合初学者学习C++网络编程。在使用muduo的时候发现了两个问题,在此做下记录。
一、muduo-0.8.2编译不通过。
根据陈硕老师的方案下载muduo-0.8.2.tar.gz(https://github.com/chenshuo/muduo/releases),发现编译不能通过,报如下错误:
error: typedef ‘T_must_be_complete_type’ locally defined but not used [-Werror=unused-local-typedefs]
typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
完整错误:
我的机器是:
Linux jacky-Virtual-Machine 4.15.0-43-generic #46~16.04.1-Ubuntu SMP Fri Dec 7 13:31:08 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
具体原因没有定位出来,网上对此讨论的不多。希望有大牛赐教下~
二、muduo-v2.0.0编译通过
想到可能是由于兼容性原因(C++项目经常出现的问题之一),选择当前最新的版本muduo-v2.0.0进行编译。
编译方式很简单,只要执行./build.sh文件即可。
编译结果在../build/release-cpp11中,但注意这里并没有include文件夹。解决方案有二:
1.将./muduo/muduo文件夹复制到/usr/include,这样就可以在自己项目中直接像include内置头文件使用了。
2.在../build/release-cpp11下创建include文件夹,将./muduo/muduo文件夹复制到include。
三、编译muduo-tutorial(https://github.com/chenshuo/muduo-tutorial)
陈硕老师给出了一个简单的案例,它是基于muduo开发的一个简单的回复客户端发送的内容。
编译过程中有两个错误(基于makefile的方式编译):
1.命名空间冲突
解决方案:去除using namespace muduo;并在Timestamp,string,CurrentThread前加上muduo::(完整代码见下)
2.没有引入boost/scoped_ptr.hpp头文件。
引入头文件:#include
完整代码如下:
#include "muduo/net/TcpServer.h"
#include "muduo/base/AsyncLogging.h"
#include "muduo/base/Logging.h"
#include "muduo/base/Thread.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include
#include
#include
#include
#include
//using namespace muduo;
using namespace muduo::net;
class EchoServer
{
public:
EchoServer(EventLoop* loop, const InetAddress& listenAddr)
: loop_(loop),
server_(loop, listenAddr, "EchoServer")
{
server_.setConnectionCallback(
boost::bind(&EchoServer::onConnection, this, _1));
server_.setMessageCallback(
boost::bind(&EchoServer::onMessage, this, _1, _2, _3));
}
void start()
{
server_.start();
}
private:
void onConnection(const TcpConnectionPtr& conn);
void onMessage(const TcpConnectionPtr& conn, Buffer* buf, muduo::Timestamp time);
EventLoop* loop_;
TcpServer server_;
};
void EchoServer::onConnection(const TcpConnectionPtr& conn)
{
LOG_TRACE << conn->peerAddress().toIpPort() << " -> "
<< conn->localAddress().toIpPort() << " is "
<< (conn->connected() ? "UP" : "DOWN");
}
void EchoServer::onMessage(const TcpConnectionPtr& conn, Buffer* buf, muduo::Timestamp time)
{
muduo::string msg(buf->retrieveAllAsString());
LOG_TRACE << conn->name() << " recv " << msg.size() << " bytes at " << time.toString();
conn->send(msg);
}
int kRollSize = 500*1000*1000;
boost::scoped_ptr g_asyncLog;
void asyncOutput(const char* msg, int len)
{
g_asyncLog->append(msg, len);
}
void setLogging(const char* argv0)
{
muduo::Logger::setOutput(asyncOutput);
char name[256];
strncpy(name, argv0, 256);
g_asyncLog.reset(new muduo::AsyncLogging(::basename(name), kRollSize));
g_asyncLog->start();
}
int main(int argc, char* argv[])
{
setLogging(argv[0]);
LOG_INFO << "pid = " << getpid() << ", tid = " << muduo::CurrentThread::tid();
EventLoop loop;
InetAddress listenAddr(2007);
EchoServer server(&loop, listenAddr);
server.start();
loop.loop();
}
四、运行echo
客户端执行:
echo "hello world" | nc localhost 2007
结果: