-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7648362
commit c6f6433
Showing
12 changed files
with
569 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"files.associations": { | ||
"memory": "cpp", | ||
"initializer_list": "cpp", | ||
"list": "cpp", | ||
"type_traits": "cpp", | ||
"vector": "cpp", | ||
"xhash": "cpp", | ||
"xstring": "cpp", | ||
"xutility": "cpp", | ||
"system_error": "cpp" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
MUDUO_DIRECTORY ?= $(HOME)/code_test/muduo/build/release-install | ||
#MUDUO_DIRECTORY ?= $(HOME)/build/install | ||
MUDUO_INCLUDE = $(MUDUO_DIRECTORY)/include | ||
MUDUO_LIBRARY = $(MUDUO_DIRECTORY)/lib | ||
SRC = ./ | ||
|
||
CXXFLAGS = -g -O0 -Wall -Wextra -Werror \ | ||
-Wconversion -Wno-unused-parameter \ | ||
-Wold-style-cast -Woverloaded-virtual \ | ||
-Wpointer-arith -Wshadow -Wwrite-strings \ | ||
-march=native -rdynamic \ | ||
-I$(MUDUO_INCLUDE) | ||
|
||
LDFLAGS = -L$(MUDUO_LIBRARY) -lmuduo_net -lmuduo_base -lpthread -lrt -std=c++11 | ||
|
||
all: chat_server chat_client chat_client2 chat_server2 | ||
clean: | ||
rm -f chat_server core | ||
|
||
chat_server: $(SRC)/server.cc | ||
g++ $(CXXFLAGS) -o $@ $^ $(LDFLAGS) | ||
|
||
chat_server2: $(SRC)/server2.cc | ||
g++ $(CXXFLAGS) -o $@ $^ $(LDFLAGS) | ||
|
||
chat_client: $(SRC)/client.cc | ||
g++ $(CXXFLAGS) -o $@ $^ $(LDFLAGS) | ||
|
||
chat_client2: $(SRC)/client2.cc | ||
g++ $(CXXFLAGS) -o $@ $^ $(LDFLAGS) | ||
|
||
.PHONY: all clean |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#include <muduo/base/Logging.h> | ||
#include <muduo/net/Endian.h> | ||
#include <muduo/net/EventLoop.h> | ||
#include <muduo/net/InetAddress.h> | ||
#include <muduo/net/TcpClient.h> | ||
|
||
#include <boost/bind.hpp> | ||
|
||
#include <utility> | ||
#include <iostream> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
|
||
using namespace muduo; | ||
using namespace muduo::net; | ||
|
||
class TimeClient : boost::noncopyable | ||
{ | ||
public: | ||
TimeClient(EventLoop* loop, const InetAddress& serverAddr) | ||
: loop_(loop), | ||
client_(loop, serverAddr, "TimeClient") | ||
{ | ||
client_.setConnectionCallback( | ||
boost::bind(&TimeClient::onConnection, this, _1)); | ||
client_.setMessageCallback( | ||
boost::bind(&TimeClient::onMessage, this, _1, _2, _3)); | ||
// client_.enableRetry(); | ||
} | ||
|
||
void connect() | ||
{ | ||
client_.connect(); | ||
} | ||
|
||
private: | ||
|
||
EventLoop* loop_; | ||
TcpClient client_; | ||
|
||
void onConnection(const TcpConnectionPtr& conn) | ||
{ | ||
LOG_INFO << conn->localAddress().toIpPort() << " -> " | ||
<< conn->peerAddress().toIpPort() << " is " | ||
<< (conn->connected() ? "UP" : "DOWN"); | ||
|
||
string str = "hello world"; | ||
StringPiece message(str); | ||
muduo::net::Buffer buf; | ||
buf.append(message.data(), message.size()); | ||
|
||
|
||
conn->send(&buf); | ||
if (!conn->connected()) | ||
{ | ||
loop_->quit(); | ||
} | ||
} | ||
|
||
void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime) | ||
{ | ||
// if (buf->readableBytes() >= sizeof(int32_t)) | ||
// { | ||
// const void* data = buf->peek(); | ||
// int32_t be32 = *static_cast<const int32_t*>(data); | ||
// buf->retrieve(sizeof(int32_t)); | ||
// time_t time = sockets::networkToHost32(be32); | ||
// Timestamp ts(implicit_cast<uint64_t>(time) * Timestamp::kMicroSecondsPerSecond); | ||
// LOG_INFO << "Server time = " << time << ", " << ts.toFormattedString(); | ||
// } | ||
// else | ||
// { | ||
// LOG_INFO << conn->name() << " no enough data " << buf->readableBytes() | ||
// << " at " << receiveTime.toFormattedString(); | ||
// } | ||
std::cout<<buf->readableBytes()<<std::endl; | ||
if(buf->readableBytes() >= 4) // kHeaderLen == 4 | ||
{ | ||
const void* data = buf->peek(); | ||
int32_t be32 = *static_cast<const int32_t*>(data); // SIGBUS | ||
const int32_t len = muduo::net::sockets::networkToHost32(be32); | ||
std::cout<<"[msg len] "<<len<<std::endl; | ||
|
||
|
||
buf->retrieve(4); | ||
muduo::string message(buf->peek(), len); | ||
buf->retrieve(len); | ||
std::cout<<"[msg ] "<<message<<std::endl; | ||
} | ||
} | ||
}; | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
LOG_INFO << "pid = " << getpid(); | ||
if (argc > 1) | ||
{ | ||
EventLoop loop; | ||
InetAddress serverAddr(argv[1], 7001); | ||
|
||
TimeClient timeClient(&loop, serverAddr); | ||
timeClient.connect(); | ||
loop.loop(); | ||
} | ||
else | ||
{ | ||
printf("Usage: %s host_ip\n", argv[0]); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include <muduo/base/Logging.h> | ||
#include <muduo/net/Endian.h> | ||
#include <muduo/net/EventLoop.h> | ||
#include <muduo/net/InetAddress.h> | ||
#include <muduo/net/TcpClient.h> | ||
#include <muduo/base/Mutex.h> | ||
#include <boost/bind.hpp> | ||
|
||
#include <utility> | ||
#include <iostream> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <muduo/net/EventLoopThread.h> | ||
#include <iostream> | ||
|
||
using namespace muduo; | ||
using namespace muduo::net; | ||
|
||
class TimeClient : boost::noncopyable | ||
{ | ||
public: | ||
TimeClient(EventLoop* loop, const InetAddress& serverAddr) | ||
: loop_(loop), | ||
client_(loop, serverAddr, "TimeClient") | ||
{ | ||
client_.setConnectionCallback( | ||
boost::bind(&TimeClient::onConnection, this, _1)); | ||
client_.setMessageCallback( | ||
boost::bind(&TimeClient::onMessage, this, _1, _2, _3)); | ||
// client_.enableRetry(); | ||
} | ||
|
||
void connect() | ||
{ | ||
client_.connect(); | ||
} | ||
|
||
void mysend(muduo::net::TcpConnection* conn, const muduo::StringPiece& message) | ||
{ | ||
muduo::net::Buffer buf; | ||
buf.append(message.data(), message.size()); | ||
int32_t len = static_cast<int32_t>(message.size()); | ||
int32_t be32 = muduo::net::sockets::hostToNetwork32(len); | ||
buf.prepend(&be32, sizeof be32); | ||
conn->send(&buf); | ||
} | ||
|
||
void write(const StringPiece& message) | ||
{ | ||
MutexLockGuard lock(mutex_); | ||
if (connection_) | ||
{ | ||
mysend(get_pointer(connection_), message); | ||
} | ||
} | ||
|
||
void disconnect() | ||
{ | ||
client_.disconnect(); | ||
} | ||
|
||
private: | ||
|
||
EventLoop* loop_; | ||
TcpClient client_; | ||
MutexLock mutex_; | ||
TcpConnectionPtr connection_; | ||
|
||
void onConnection(const TcpConnectionPtr& conn) | ||
{ | ||
LOG_INFO << conn->localAddress().toIpPort() << " -> " | ||
<< conn->peerAddress().toIpPort() << " is " | ||
<< (conn->connected() ? "UP" : "DOWN"); | ||
|
||
if (!conn->connected()) | ||
{ | ||
loop_->quit(); | ||
} | ||
else | ||
{ | ||
connection_ = conn; | ||
} | ||
} | ||
|
||
void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime) | ||
{ | ||
std::cout<<buf->readableBytes()<<std::endl; | ||
if(buf->readableBytes() >= 4) // kHeaderLen == 4 | ||
{ | ||
|
||
const void* data = buf->peek(); | ||
int32_t be32 = *static_cast<const int32_t*>(data); // SIGBUS | ||
const int32_t len = muduo::net::sockets::networkToHost32(be32); | ||
std::cout<<"[msg len] "<<len<<std::endl; | ||
|
||
|
||
buf->retrieve(4); | ||
muduo::string message(buf->peek(), len); | ||
buf->retrieve(len); | ||
std::cout<<"[msg ] "<<message<<std::endl; | ||
} | ||
} | ||
}; | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
LOG_INFO << "pid = " << getpid(); | ||
if (argc > 1) | ||
{ | ||
EventLoopThread loopThread; | ||
InetAddress serverAddr(argv[1], 7001); | ||
|
||
TimeClient timeClient(loopThread.startLoop(), serverAddr); | ||
timeClient.connect(); | ||
//loop.loop(); | ||
|
||
std::string line; | ||
while(std::getline(std::cin,line)) | ||
{ | ||
|
||
timeClient.write(line); | ||
} | ||
timeClient.disconnect(); | ||
} | ||
else | ||
{ | ||
printf("Usage: %s host_ip\n", argv[0]); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#ifndef MUDUO_EXAMPLES_ASIO_CHAT_CODEC_H | ||
#define MUDUO_EXAMPLES_ASIO_CHAT_CODEC_H | ||
|
||
#include <muduo/base/Logging.h> | ||
#include <muduo/net/Buffer.h> | ||
#include <muduo/net/Endian.h> | ||
#include <muduo/net/TcpConnection.h> | ||
|
||
#include <boost/function.hpp> | ||
#include <boost/noncopyable.hpp> | ||
|
||
class LengthHeaderCodec : boost::noncopyable | ||
{ | ||
public: | ||
typedef boost::function<void(const muduo::net::TcpConnectionPtr &, const muduo::string &message, muduo::Timestamp)> | ||
StringMessageCallback; | ||
|
||
explicit LengthHeaderCodec(const StringMessageCallback &cb) : messageCallback_(cb) | ||
{ | ||
} | ||
|
||
void onMessage(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer *buf, muduo::Timestamp receiveTime) | ||
{ | ||
while (buf->readableBytes() >= kHeaderLen) // kHeaderLen == 4 | ||
{ | ||
// FIXME: use Buffer::peekInt32() | ||
const void *data = buf->peek(); | ||
int32_t be32 = *static_cast<const int32_t *>(data); // SIGBUS | ||
const int32_t len = muduo::net::sockets::networkToHost32(be32); | ||
if (len > 65536 || len < 0) | ||
{ | ||
LOG_ERROR << "Invalid length " << len; | ||
conn->shutdown(); // FIXME: disable reading | ||
break; | ||
} | ||
else if (buf->readableBytes() >= len + kHeaderLen) | ||
{ | ||
buf->retrieve(kHeaderLen); | ||
muduo::string message(buf->peek(), len); | ||
messageCallback_(conn, message, receiveTime); | ||
buf->retrieve(len); | ||
} | ||
else | ||
{ | ||
break; | ||
} | ||
} | ||
} | ||
|
||
// FIXME: TcpConnectionPtr | ||
void send(muduo::net::TcpConnection *conn, | ||
const muduo::StringPiece &message) | ||
{ | ||
muduo::net::Buffer buf; | ||
buf.append(message.data(), message.size()); | ||
int32_t len = static_cast<int32_t>(message.size()); | ||
int32_t be32 = muduo::net::sockets::hostToNetwork32(len); | ||
buf.prepend(&be32, sizeof be32); | ||
conn->send(&buf); | ||
} | ||
|
||
private: | ||
StringMessageCallback messageCallback_; | ||
const static size_t kHeaderLen = sizeof(int32_t); | ||
}; | ||
|
||
#endif // MUDUO_EXAMPLES_ASIO_CHAT_CODEC_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 实现muduo里面的chatserver的例子 | ||
|
||
|
||
这个是利用muduo实现一个应用层的广播。另外,就是加上了**tcp的分包和拆包机制**。 | ||
|
||
client1.cc 和 server1.cc 是一个半成品,理解起来更快一点。 | ||
|
||
client2.cc 和 server2.cc 是写完成的东西。 | ||
|
||
|
||
--- | ||
|
||
## 收获 | ||
|
||
* 拆包的时候,有一个写法很好 | ||
``` | ||
const void *data = buf->peek(); //拿到的数据 | ||
int32_t be32 = *static_cast<const int32_t *>(data); //获得头部的int | ||
``` |
Oops, something went wrong.