From 35030998472451c8b0a0c57271753117cf603ab0 Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 14:52:05 +0800 Subject: [PATCH 01/31] update --- README.md | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/README.md b/README.md index fa5afb3..27c3279 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,3 @@ # sim -C++ network server framework, `nc` and `telnet` friendly. - - -#demo - - #include "sim/sim.h" - - class MyHandler : public sim::Handler - { - public: - virtual sim::HandlerState proc(const sim::Request &req, sim::Response *resp){ - std::string cmd = req.msg.type(); - if(cmd == "ping"){ - resp->msg.add("ok"); - resp->msg.add("pong"); - }else{ - resp->msg.add("ok"); - resp->msg.add(cmd); - } - return this->resp(); - } - }; - - int main(int argc, char **argv){ - const char *ip = "127.0.0.1"; - int port = 8800; - sim::Server *serv = sim::Server::listen(ip, port); - if(!serv){ - log_fatal("%s", strerror(errno)); - exit(0); - } - log_info("server listen on %s:%d", ip, port); - - MyHandler handler; - serv->add_handler(&handler); - - serv->loop(); - return 0; - } - - +C++ network server framework. From 8dd4252cebf76ad8d3de7e5f6e0a24b17a94753b Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 14:55:35 +0800 Subject: [PATCH 02/31] update --- src/Makefile | 23 ++-- src/client/Makefile | 16 --- src/client/client.cpp | 52 -------- src/client/client.h | 29 ----- src/client/demo.cpp | 29 ----- src/decoder.cpp | 92 -------------- src/decoder.h | 28 ----- src/handler.cpp | 47 ------- src/handler.h | 99 --------------- src/message.cpp | 89 -------------- src/message.h | 41 ------- src/server.cpp | 278 ------------------------------------------ src/server.h | 44 ------- src/sim.cpp | 136 --------------------- src/sim.h | 36 ------ 15 files changed, 10 insertions(+), 1029 deletions(-) delete mode 100644 src/client/Makefile delete mode 100644 src/client/client.cpp delete mode 100644 src/client/client.h delete mode 100644 src/client/demo.cpp delete mode 100644 src/decoder.cpp delete mode 100644 src/decoder.h delete mode 100644 src/handler.cpp delete mode 100644 src/handler.h delete mode 100644 src/message.cpp delete mode 100644 src/message.h delete mode 100644 src/server.cpp delete mode 100644 src/server.h delete mode 100644 src/sim.cpp delete mode 100644 src/sim.h diff --git a/src/Makefile b/src/Makefile index 29408a4..a18d759 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,26 +1,23 @@ include ../build_config.mk CFLAGS += -OBJS = sim.o message.o decoder.o link.o handler.o server.o \ - fde.o log.o app.o config.o +OBJS= LIB=libsim.a -HEADER_FILES=sim.h message.h decoder.h fde.h link.h handler.h server.h +HEADER_FILES= UTIL_HEADERS=util/thread.h util/strings.h util/log.h util/config.h util/app.h all: $(OBJS) - mkdir -p $(HEADER_OUTPUT_DIR)/util - ar -cru $(OUTPUT_DIR)/$(LIB) ${OBJS} - cp $(HEADER_FILES) $(HEADER_OUTPUT_DIR) - cp $(UTIL_HEADERS) $(HEADER_OUTPUT_DIR)/util + #mkdir -p $(HEADER_OUTPUT_DIR)/util + #ar -cru $(OUTPUT_DIR)/$(LIB) ${OBJS} + #cp $(HEADER_FILES) $(HEADER_OUTPUT_DIR) + #cp $(UTIL_HEADERS) $(HEADER_OUTPUT_DIR)/util fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp ${CXX} ${CFLAGS} -c fde.cpp -app.o: util/app.h util/app.cpp - $(CXX) ${CFLAGS} -c util/app.cpp -log.o: util/log.h util/log.cpp - $(CXX) ${CFLAGS} -c util/log.cpp -config.o: util/config.h util/config.cpp - $(CXX) ${CFLAGS} -c util/config.cpp +# log.o: util/log.h util/log.cpp +# $(CXX) ${CFLAGS} -c util/log.cpp +# config.o: util/config.h util/config.cpp +# $(CXX) ${CFLAGS} -c util/config.cpp .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ diff --git a/src/client/Makefile b/src/client/Makefile deleted file mode 100644 index 2d36cde..0000000 --- a/src/client/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -include ../../build_config.mk -CFLAGS += -I../ -OUTPUT_DIR=../../api/cpp - -all: lib - ${CXX} -I$(OUTPUT_DIR) -o demo demo.cpp $(OUTPUT_DIR)/libsim-client.a - -lib: client.h client.cpp - $(CXX) $(CFLAGS) -c client.cpp - ar -cru libsim-client.a\ - client.o\ - ../sim.o ../message.o ../decoder.o ../link.o - cp client.h ../message.h libsim-client.a ../../api/cpp - -clean: - rm -rf *.o *.a *.out diff --git a/src/client/client.cpp b/src/client/client.cpp deleted file mode 100644 index 9db414e..0000000 --- a/src/client/client.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "client.h" -#include "link.h" - -namespace sim{ - -Client::Client(){ - link = NULL; -} - -Client::~Client(){ - delete link; -} - -Client* Client::connect(const char *ip, int port){ - return Client::connect(std::string(ip), port); -} - -Client* Client::connect(const std::string &ip, int port){ - Link *link = Link::connect(ip, port); - if(!link){ - return NULL; - } - Client *client = new Client(); - client->link = link; - return client; -} - -int Client::send(const Message &msg){ - this->link->send(msg); - return this->link->flush(); -} - -int Client::recv(Message *msg){ - while(1){ - int ret; - ret = link->recv(msg); - if(ret == -1){ - return -1; - }else if(ret == 1){ - return 1; - }else{ - // - } - - ret = link->read(); - if(ret <= 0){ - return -1; - } - } -} - -}; // namespace sim diff --git a/src/client/client.h b/src/client/client.h deleted file mode 100644 index 6b57e46..0000000 --- a/src/client/client.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef SIM_CLIENT_H_ -#define SIM_CLIENT_H_ - -#include "message.h" - -namespace sim{ - -class Link; -std::string encode(const std::string s, bool force_ascii=false); -std::string decode(const std::string s); - -class Client -{ -public: - static Client* connect(const char *ip, int port); - static Client* connect(const std::string &ip, int port); - - int send(const Message &msg); // blocking send - int recv(Message *msg); // blocking recv - - ~Client(); -private: - Client(); - Link *link; -}; - -}; // namespace sim - -#endif diff --git a/src/client/demo.cpp b/src/client/demo.cpp deleted file mode 100644 index a87b0ed..0000000 --- a/src/client/demo.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "client.h" - -int main(int argc, char **argv){ - printf("Usage: %s [ip] [port]\n", argv[0]); - const char *ip = (argc >= 2)? argv[1] : "127.0.0.1"; - int port = (argc >= 3)? atoi(argv[2]) : 8800; - - // connect to server - sim::Client *client = sim::Client::connect(ip, port); - if(client == NULL){ - printf("fail to connect to server!\n"); - return 0; - } - - sim::Message req, resp; - req.set_type("ping"); - client->send(req); - client->recv(&resp); - printf("resp: %s\n", resp.encode().c_str()); - - delete client; - return 0; -} diff --git a/src/decoder.cpp b/src/decoder.cpp deleted file mode 100644 index aed34e2..0000000 --- a/src/decoder.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "util/strings.h" -#include "util/log.h" -#include "sim.h" - -namespace sim{ - -const static int BUF_RESIZE_TRIGGER = 16 * 1024; - -int Decoder::push(const char *buf, int len){ - buffer.append(buf, len); - //log_debug("'%s'", str_escape(buffer).c_str()); - return len; -} - -int Decoder::parse(Message *msg){ - msg->reset(); - - if(buffer_offset >= BUF_RESIZE_TRIGGER){ - //log_debug("resize buffer"); - buffer = std::string(buffer.data() + buffer_offset, buffer.size() - buffer_offset); - buffer_offset = 0; - } - - while(buffer.size() > buffer_offset && isspace(buffer[buffer_offset])){ - buffer_offset ++; - } - if(buffer.size() == buffer_offset){ - return 0; - } - - const char *key = buffer.data() + buffer_offset; - const char *msg_end = (const char *)memchr(key, sim::MSG_END_BYTE, buffer.size() - buffer_offset); - if(!msg_end){ - return 0; - } - int msg_len = msg_end - key + 1; - int size = msg_len; - - int auto_tag = 0; - while(1){ - int key_len = 0; - int val_len; - int tag; - - const char *end; - end = (const char *)memchr(key, sim::KV_END_BYTE, size); - // 兼容最后一个 空格 被省略的情况 - if(end == NULL){ - end = msg_end; - } - - const char *val = (const char *)memchr(key, sim::KV_SEP_BYTE, end - key); - if(val == NULL){ - val = key; - tag = auto_tag; - }else{ - val ++; - key_len = val - key - 1; - size -= key_len + 1; - std::string key_s(key, key_len); - tag = str_to_int(key_s); - } - - val_len = end - val; - size -= val_len + 1; - - if(val_len > 0 && val[val_len - 1] == '\r'){ - val_len -= 1; - } - - //printf("%u key: %u, val: %u\n", __LINE__, key_len, val_len); - - std::string val_s(val, val_len); - msg->set(tag, val_s); - - key = end + 1; - auto_tag = tag + 1; - - if(key >= msg_end){ - std::map::iterator it; - for(it=msg->fields_.begin(); it!=msg->fields_.end(); it++){ - it->second = sim::decode(it->second); - } - buffer_offset += msg_len; - //log_debug("msg.len: %d, buffer.len: %d", msg_len, buffer.size()); - return 1; - } - } - return 0; -} - -}; // namespace sim diff --git a/src/decoder.h b/src/decoder.h deleted file mode 100644 index 08b6227..0000000 --- a/src/decoder.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef SIM_DECODER_H_ -#define SIM_DECODER_H_ - -#include -#include "message.h" - -namespace sim{ - -class Decoder{ -public: - Decoder(){ - buffer_offset = 0; - } - // 当你从 socket 中读到数据, 或者从文件中读到数据时, 将数据压入解码器的数据缓冲区 - int push(const char *buf, int len); - // 解析缓冲区中的数据, 如果解析出一个完整的 FIX 报文, 返回 1, - // 如果数据不足一个报文, 返回 0, 你应该继续读取数据并压入解码器. - // 如果出错(如系统错误), 返回 -1. - int parse(Message *msg); -private: - // TODO: 优化成 ring buffer, 直接从 socket 里读 - std::string buffer; - int buffer_offset; -}; - -}; // namespace sim - -#endif diff --git a/src/handler.cpp b/src/handler.cpp deleted file mode 100644 index a99d1d0..0000000 --- a/src/handler.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "util/log.h" -#include "handler.h" -#include "util/thread.h" - -namespace sim{ - -int Handler::m_init(){ - resps = new SelectableQueue(); - return this->init(); -} - -int Handler::m_free(){ - delete resps; - return this->free(); -} - -int Handler::fd(){ - return resps->fd(); -} - -HandlerState Handler::accept(const Session &sess){ - return HANDLE_OK; -} - -HandlerState Handler::close(const Session &sess){ - return HANDLE_OK; -} - -HandlerState Handler::proc(const Request &req, Response *resp){ - return HANDLE_OK; -} - -void Handler::async_send(Response *resp){ - this->resps->push(resp); -} - -Response* Handler::handle(){ - while(this->resps->size() > 0){ - Response *resp; - if(this->resps->pop(&resp) == 1 && resp != NULL){ - return resp; - } - } - return NULL; -} - -}; // namespace sim diff --git a/src/handler.h b/src/handler.h deleted file mode 100644 index 4e181a9..0000000 --- a/src/handler.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef SIM_HANDLER_H_ -#define SIM_HANDLER_H_ - -#include "link.h" -#include "message.h" - -template -class SelectableQueue; - -namespace sim{ - -class Session -{ -public: - int64_t id; - Link *link; - - Session(){ - static int64_t inc = 0; - this->id = inc ++; - this->link = NULL; - } - ~Session(){ - } -}; - -class Request{ -public: - Message msg; - Session sess; - - double stime; - double time_wait; - double time_proc; -}; - -class Response{ -public: - Message msg; - Session sess; -}; - - -typedef enum{ - HANDLE_OK = 0, - HANDLE_FAIL = 1, - HANDLE_RESP = 1, -}HandlerState; - - -class Handler -{ -public: - Handler(){}; - virtual ~Handler(){}; - - // 当有新客户端进来时, 此方法被调用. 如果返回 HANDLE_FAIL, 连接将被关闭. - virtual HandlerState accept(const Session &sess); - // 当客户端被关闭时, 此方法被调用. - virtual HandlerState close(const Session &sess); - - // 当收到客户端的一个请求报文时, 调用此方法. - // 如果有响应需要立即返回给客户端, 将响应加到 resp 中, 并返回 HANDLE_RESP; - virtual HandlerState proc(const Request &req, Response *resp); - - virtual int init(){ return 0; } - virtual int free(){ return 0; } - //virtual void thread(); - - /***** 以下是特殊方法, 你一般不需要关心. *****/ - - // 此方法默认返回异步响应队列的 fd, 你可以重写此方法, 返回你自己的 fd. - virtual int fd(); - - // 当 fd() 有可读事件时, 本函数被调用. - // 如果此方法有响应需要立即返回, 请返回 Response 实例, 外面会负责释放内存. - // 如无响应, 返回 NULL. - virtual Response* handle(); - -protected: - // 将异步响应加入到队列中, 该响应会被发送给客户端. - // 如果 Handler 是多线程的, 可以会调用本方法将响应发给客户端. - void async_send(Response *resp); - - HandlerState ok(){ return HANDLE_OK; }; - HandlerState fail(){ return HANDLE_FAIL; }; - HandlerState resp(){ return HANDLE_RESP; }; - -private: - SelectableQueue *resps; - - int m_init(); - int m_free(); - friend class Server; -}; - -}; // namespace sim - -#endif diff --git a/src/message.cpp b/src/message.cpp deleted file mode 100644 index dbac65f..0000000 --- a/src/message.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "util/strings.h" -#include "sim.h" - -namespace sim{ - -Message::Message(){ -} - -Message::~Message(){ -} - -void Message::reset(){ - fields_.clear(); -} - -std::string Message::type() const{ - return type_; -} - -void Message::set_type(const std::string &type){ - type_ = type; -} - -void Message::set(int tag, int32_t val){ - this->set(tag, (int64_t)val); -} - -void Message::set(int tag, int64_t val){ - this->set(tag, str(val)); -} - -void Message::set(int tag, const char *val){ - this->set(tag, str(val)); -} - -void Message::set(int tag, const std::string &val){ - if(tag == 0){ - this->set_type(val); - } - fields_[tag] = val; -} - -void Message::add(const std::string &val){ - int tag; - std::map::const_reverse_iterator it; - it = fields_.rbegin(); - if(it == fields_.rend()){ - tag = 0; - }else{ - tag = it->first + 1; - } - this->set(tag, val); -} - -const std::string* Message::get(int tag) const{ - std::map::const_iterator it; - it = fields_.find(tag); - if(it == fields_.end()){ - return NULL; - } - return &(it->second); -} - -static std::string encode_field(int tag, const std::string &val){ - std::string buffer; - buffer.append(str(tag)); - buffer.push_back(sim::KV_SEP_BYTE); - buffer.append(sim::encode(val)); - buffer.push_back(sim::KV_END_BYTE); - return buffer; -} - -std::string Message::encode() const{ - std::string buffer; - buffer.append(encode_field(0, this->type())); - std::map::const_iterator it; - for(it=fields_.begin(); it!=fields_.end(); it++){ - int tag = it->first; - if(tag == 0){ - continue; - } - const std::string &val = it->second; - buffer.append(encode_field(tag, val)); - } - buffer[buffer.size()-1] = sim::MSG_END_BYTE; - return buffer; -} - -}; // namespace sim diff --git a/src/message.h b/src/message.h deleted file mode 100644 index 8ed7fd2..0000000 --- a/src/message.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef SIM_MESSAGE_H_ -#define SIM_MESSAGE_H_ - -#include -#include -#include -#include - -namespace sim{ - -class Message{ -public: - Message(); - ~Message(); - - void reset(); - - std::string type() const; - void set_type(const std::string &type); - - void add(const std::string &val); // 自增 tag, 从 0 开始 - void set(int tag, int32_t val); - void set(int tag, int64_t val); - void set(int tag, const char *val); - void set(int tag, const std::string &val); - const std::string* get(int tag) const; - - std::string encode() const; - const std::map* fields() const{ - return &fields_; - } - -private: - std::string type_; - std::map fields_; - friend class Decoder; -}; - -}; // namespace sim - -#endif diff --git a/src/server.cpp b/src/server.cpp deleted file mode 100644 index f69005b..0000000 --- a/src/server.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include -#include -#include -#include -#include "util/log.h" -#include "sim.h" -#include "fde.h" -#include "server.h" - -#include "util/strings.h" - -static std::string msg_str(const sim::Message &msg){ - std::string ret; - const std::map *fields = msg.fields(); - std::map::const_iterator it; - char buf[50]; - int count = 0; - for(it=fields->begin(); it!=fields->end(); it++){ - if(ret.size() > 100){ - snprintf(buf, sizeof(buf), "[%d more...]", (int)fields->size() - count); - ret.append(buf); - break; - } - - int tag = it->first; - const std::string &val = it->second; - ret.append(str(tag)); - ret.push_back('='); - if(val.size() < 30){ - std::string h = sim::encode(val, true); - ret.append(h); - }else{ - sprintf(buf, "[%d]", (int)val.size()); - ret.append(buf); - } - - count ++; - if(count != (int)fields->size()){ - ret.push_back(' '); - } - } - return ret; -} - - -namespace sim{ - -const static int DEFAULT_TYPE = 0; -const static int HANDLER_TYPE = 1; - -Server::Server(){ - signal(SIGPIPE, SIG_IGN); - link_count = 0; - serv_link = NULL; - fdes = new Fdevents(); -} - -Server::~Server(){ - for(int i=0; ihandlers.size(); i++){ - Handler *handler = this->handlers[i]; - handler->m_free(); - delete handler; - } - this->handlers.clear(); - - delete serv_link; - delete fdes; -} - -Server* Server::listen(const std::string &ip, int port){ - Link *serv_link = Link::listen(ip, port); - if(!serv_link){ - return NULL; - } - - Server *ret = new Server(); - ret->serv_link = serv_link; - ret->fdes->set(serv_link->fd(), FDEVENT_IN, DEFAULT_TYPE, serv_link); - return ret; -} - -void Server::add_handler(Handler *handler){ - handler->m_init(); - this->handlers.push_back(handler); - if(handler->fd() > 0){ - fdes->set(handler->fd(), FDEVENT_IN, HANDLER_TYPE, handler); - } -} - -Session* Server::accept_session(){ - Link *link = serv_link->accept(); - if(link == NULL){ - log_error("accept failed! %s", strerror(errno)); - return NULL; - } - - link->nodelay(); - link->noblock(); - link->create_time = microtime(); - link->active_time = link->create_time; - - Session *sess = new Session(); - sess->link = link; - this->sessions[sess->id] = sess; - - for(int i=0; ihandlers.size(); i++){ - Handler *handler = this->handlers[i]; - HandlerState state = handler->accept(*sess); - if(state == HANDLE_FAIL){ - delete link; - delete sess; - return NULL; - } - } - - this->link_count ++; - log_debug("new link from %s:%d, fd: %d, links: %d", - link->remote_ip, link->remote_port, link->fd(), this->link_count); - fdes->set(link->fd(), FDEVENT_IN, DEFAULT_TYPE, sess); - - return sess; -} - -int Server::close_session(Session *sess){ - Link *link = sess->link; - for(int i=0; ihandlers.size(); i++){ - Handler *handler = this->handlers[i]; - handler->close(*sess); - } - - this->link_count --; - log_debug("delete link %s:%d, fd: %d, links: %d", - link->remote_ip, link->remote_port, link->fd(), this->link_count); - fdes->del(link->fd()); - - this->sessions.erase(sess->id); - delete link; - delete sess; - return 0; -} - -int Server::read_session(Session *sess){ - Link *link = sess->link; - if(link->error()){ - return 0; - } - - int len = link->read(); - if(len <= 0){ - this->close_session(sess); - return -1; - } - - while(1){ - Request req; - int ret = link->recv(&req.msg); - if(ret == -1){ - log_info("fd: %d, parse error, delete link", link->fd()); - this->close_session(sess); - return -1; - }else if(ret == 0){ - // 报文未就绪, 继续读网络 - break; - } - req.stime = microtime(); - req.sess = *sess; - - Response resp; - for(int i=0; ihandlers.size(); i++){ - Handler *handler = this->handlers[i]; - req.time_wait = 1000 * (microtime() - req.stime); - HandlerState state = handler->proc(req, &resp); - req.time_proc = 1000 * (microtime() - req.stime) - req.time_wait; - if(state == HANDLE_RESP){ - link->send(resp.msg); - if(link && !link->output.empty()){ - fdes->set(link->fd(), FDEVENT_OUT, DEFAULT_TYPE, sess); - } - - if(log_level() >= Logger::LEVEL_DEBUG){ - log_debug("w:%.3f,p:%.3f, req: %s resp: %s", - req.time_wait, req.time_proc, - msg_str(req.msg).c_str(), - msg_str(resp.msg).c_str()); - } - }else if(state == HANDLE_FAIL){ - this->close_session(sess); - return -1; - } - } - } - - return 0; -} - -int Server::write_session(Session *sess){ - Link *link = sess->link; - if(link->error()){ - return 0; - } - - int len = link->write(); - if(len <= 0){ - log_debug("fd: %d, write: %d, delete link", link->fd(), len); - this->close_session(sess); - return -1; - } - if(link->output.empty()){ - fdes->clr(link->fd(), FDEVENT_OUT); - } - return 0; -} - -Session* Server::get_session(int64_t sess_id){ - std::map::iterator it; - it = sessions.find(sess_id); - if(it == sessions.end()){ - return NULL; - } - return it->second; -} - -void Server::loop(){ - while(1){ - if(this->loop_once() == -1){ - break; - } - } -} - -int Server::loop_once(){ - const Fdevents::events_t *events; - events = fdes->wait(20); - if(events == NULL){ - log_fatal("events.wait error: %s", strerror(errno)); - return 0; - } - - for(int i=0; i<(int)events->size(); i++){ - const Fdevent *fde = events->at(i); - if(fde->data.ptr == serv_link){ - this->accept_session(); - }else if(fde->data.num == HANDLER_TYPE){ - Handler *handler = (Handler *)fde->data.ptr; - while(Response *resp = handler->handle()){ - Session *sess = this->get_session(resp->sess.id); - if(sess){ - Link *link = sess->link; - link->send(resp->msg); - if(link && !link->output.empty()){ - fdes->set(link->fd(), FDEVENT_OUT, DEFAULT_TYPE, sess); - } - } - delete resp; - } - }else{ - Session *sess = (Session *)fde->data.ptr; - Link *link = sess->link; - if(fde->events & FDEVENT_IN){ - if(this->read_session(sess) == -1){ - continue; - } - } - if(fde->events & FDEVENT_OUT){ - if(this->write_session(sess) == -1){ - continue; - } - } - if(link && !link->output.empty()){ - fdes->set(link->fd(), FDEVENT_OUT, DEFAULT_TYPE, sess); - } - } - } - return 0; -} - -}; // namespace sim diff --git a/src/server.h b/src/server.h deleted file mode 100644 index be07a9f..0000000 --- a/src/server.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef SIM_SERVER_H_ -#define SIM_SERVER_H_ - -#include -#include -#include -#include "link.h" -#include "handler.h" - -namespace sim{ - -class Fdevents; - -class Server -{ -public: - static Server* listen(const std::string &ip, int port); - //static Server* create(...); - Server(); - ~Server(); - - void add_handler(Handler *handler); - void loop(); - int loop_once(); - - //int send(int64_t sess_id, const Message &msg); - //int send_all(const Message &msg); -private: - Fdevents *fdes; - Link *serv_link; - int link_count; - std::map sessions; - std::vector handlers; - - Session* accept_session(); - Session* get_session(int64_t sess_id); - int close_session(Session *sess); - int read_session(Session *sess); - int write_session(Session *sess); -}; - -}; // namespace sim - -#endif diff --git a/src/sim.cpp b/src/sim.cpp deleted file mode 100644 index 174f51a..0000000 --- a/src/sim.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include "sim.h" - -namespace sim{ - -std::string version(){ - return "1.0"; -} - -std::string encode(const std::string s, bool force_ascii){ - std::string ret; - int size = (int)s.size(); - for(int i=0; i= '!' && c <= '~'){ - ret.push_back(c); - }else{ - ret.append("\\x"); - unsigned char d = c; - ret.push_back(hex[d >> 4]); - ret.push_back(hex[d & 0x0f]); - } - } - break; - } - } - return ret; -} - -inline static -int hex_int(char c){ - if(c >= '0' && c <= '9'){ - return c - '0'; - }else{ - return c - 'a' + 10; - } -} - -std::string decode(const std::string s){ - int size = (int)s.size(); - std::string ret; - for(int i=0; i= size - 1){ - break; - } - char c2 = s[++i]; - switch(c2){ - case 's': - ret.push_back(' '); - break; - case '\\': - ret.push_back('\\'); - break; - case 'a': - ret.push_back('\a'); - break; - case 'b': - ret.push_back('\b'); - break; - case 'f': - ret.push_back('\f'); - break; - case 'v': - ret.push_back('\v'); - break; - case 'r': - ret.push_back('\r'); - break; - case 'n': - ret.push_back('\n'); - break; - case 't': - ret.push_back('\t'); - break; - case '0': - ret.push_back('\0'); - break; - case 'x': - if(i < size - 2){ - char c3 = s[++i]; - char c4 = s[++i]; - ret.push_back((char)((hex_int(c3) << 4) + hex_int(c4))); - } - break; - default: - ret.push_back(c2); - break; - } - } - return ret; -} - -}; // namespace sim - diff --git a/src/sim.h b/src/sim.h deleted file mode 100644 index 2f641f1..0000000 --- a/src/sim.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SIM_SIM_H_ -#define SIM_SIM_H_ - -#include -#include -#include "message.h" -#include "decoder.h" -#include "fde.h" -#include "link.h" -#include "server.h" -#include "handler.h" -#include "util/config.h" -#include "util/app.h" -#include "util/log.h" - -namespace sim{ - -const static char KV_SEP_BYTE = '='; -const static char KV_END_BYTE = ' '; -const static char MSG_END_BYTE = '\n'; - - -inline static -double microtime(){ - struct timeval now; - gettimeofday(&now, NULL); - double ret = now.tv_sec + now.tv_usec/1000.0/1000.0; - return ret; -} - -std::string encode(const std::string s, bool force_ascii=false); -std::string decode(const std::string s); - -}; // namespace sim - -#endif From a7a2babc6958d37dc09ab213e73d30245334dfb9 Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 15:22:12 +0800 Subject: [PATCH 03/31] update --- src/core/line_message.h | 0 src/{ => net}/fde.cpp | 0 src/{ => net}/fde.h | 0 src/{ => net}/fde_epoll.cpp | 0 src/{ => net}/fde_select.cpp | 0 src/tcp_link.h | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 36 insertions(+) create mode 100644 src/core/line_message.h rename src/{ => net}/fde.cpp (100%) rename src/{ => net}/fde.h (100%) rename src/{ => net}/fde_epoll.cpp (100%) rename src/{ => net}/fde_select.cpp (100%) create mode 100644 src/tcp_link.h diff --git a/src/core/line_message.h b/src/core/line_message.h new file mode 100644 index 0000000..e69de29 diff --git a/src/fde.cpp b/src/net/fde.cpp similarity index 100% rename from src/fde.cpp rename to src/net/fde.cpp diff --git a/src/fde.h b/src/net/fde.h similarity index 100% rename from src/fde.h rename to src/net/fde.h diff --git a/src/fde_epoll.cpp b/src/net/fde_epoll.cpp similarity index 100% rename from src/fde_epoll.cpp rename to src/net/fde_epoll.cpp diff --git a/src/fde_select.cpp b/src/net/fde_select.cpp similarity index 100% rename from src/fde_select.cpp rename to src/net/fde_select.cpp diff --git a/src/tcp_link.h b/src/tcp_link.h new file mode 100644 index 0000000..1888274 --- /dev/null +++ b/src/tcp_link.h @@ -0,0 +1,36 @@ +class Buffer +{ +public: +}; + +class Link +{ +public: + int fd() const; + Buffer* buffer() const; + + virtual int net_read() = 0; + virtual int net_write() = 0; + + virtual int send(Message &msg) = 0; +}; + +class Parser +{ +public: + virtual Message* parse(Buffer *buffer) = 0; +}; + +class Message +{ +public: + virtual Buffer* encode() = 0; +}; + +class Server +{ +public: + Link* link() const; + Parser* parser() const; +}; + From 82df81f0a317cd3c1beea39b21cc549bc6b5dbb0 Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 15:23:07 +0800 Subject: [PATCH 04/31] update --- src/{link.cpp => link-.cpp} | 0 src/{link.h => link-.h} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{link.cpp => link-.cpp} (100%) rename src/{link.h => link-.h} (100%) diff --git a/src/link.cpp b/src/link-.cpp similarity index 100% rename from src/link.cpp rename to src/link-.cpp diff --git a/src/link.h b/src/link-.h similarity index 100% rename from src/link.h rename to src/link-.h From b3d2e43188753c8ae0b6c98a2211b335eefa7b9b Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 16:05:43 +0800 Subject: [PATCH 05/31] update --- src/buffer.cpp | 35 +++++++++++++++++++++++++++++++ src/buffer.h | 17 +++++++++++++++ src/{core => line}/line_message.h | 0 src/{link-.cpp => link-.cc} | 0 src/tcp_link.h | 30 +++++++++++++++++++++----- 5 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/buffer.cpp create mode 100644 src/buffer.h rename src/{core => line}/line_message.h (100%) rename src/{link-.cpp => link-.cc} (100%) diff --git a/src/buffer.cpp b/src/buffer.cpp new file mode 100644 index 0000000..0534455 --- /dev/null +++ b/src/buffer.cpp @@ -0,0 +1,35 @@ +#include "buffer.h" + +Buffer::Buffer(){ + _size = 0; + _capacity = 1024; + _buf = malloc(_capacity); +} + +Buffer::~Buffer(){ + free(_buf); +} + +int Buffer::size() const{ + return _size; +} + +char* Buffer::data(){ + return _buf; +} + +int Buffer::remove(int count){ + memmove(_buf + count, _buf, _size - count); + _size -= count; + return count; +} + +int Buffer::append(char *buf, int count){ + if(_size + count > _capacity){ + _capacity = _size + count; + _buf = realloc(_buf, _capacity); + } + memcpy(_buf + _size, buf, count); + _size += count; + return count; +} diff --git a/src/buffer.h b/src/buffer.h new file mode 100644 index 0000000..b6c5758 --- /dev/null +++ b/src/buffer.h @@ -0,0 +1,17 @@ +class Buffer +{ +public: + Buffer(); + ~Buffer(); + + int size() const; + char* data(); + + int remove(int count); + int append(char *buf, int len); + +private: + int _size; + char *_buf; + int _capacity; +}; diff --git a/src/core/line_message.h b/src/line/line_message.h similarity index 100% rename from src/core/line_message.h rename to src/line/line_message.h diff --git a/src/link-.cpp b/src/link-.cc similarity index 100% rename from src/link-.cpp rename to src/link-.cc diff --git a/src/tcp_link.h b/src/tcp_link.h index 1888274..0e419e7 100644 --- a/src/tcp_link.h +++ b/src/tcp_link.h @@ -1,7 +1,3 @@ -class Buffer -{ -public: -}; class Link { @@ -18,7 +14,25 @@ class Link class Parser { public: - virtual Message* parse(Buffer *buffer) = 0; + virtual ParseStatus parse(Buffer *buffer) = 0; +}; + +class ParseStatus +{ +public: + Message* message(); + + bool ok() const; + bool none() const; + bool error() const; + + void set_ok(Message *msg); + void set_none(); + void set_error(); + +private: + int code; + Message *msg; }; class Message @@ -29,6 +43,12 @@ class Message class Server { +public: + Link* link() const; +}; + +class Session +{ public: Link* link() const; Parser* parser() const; From 00caa1e98bcb428d2b84b659a4e48d6610cf2991 Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 16:46:29 +0800 Subject: [PATCH 06/31] update --- src/buffer.cpp | 8 +++++--- src/buffer.h | 7 ++++++- src/line/Makefile | 13 +++++++++++++ src/line/line_message.cpp | 16 ++++++++++++++++ src/line/line_message.h | 19 +++++++++++++++++++ src/line/line_parser.cpp | 24 ++++++++++++++++++++++++ src/line/line_parser.h | 14 ++++++++++++++ src/message.h | 12 ++++++++++++ src/parser.cpp | 34 ++++++++++++++++++++++++++++++++++ src/parser.h | 35 +++++++++++++++++++++++++++++++++++ src/tcp_link.h | 29 ----------------------------- 11 files changed, 178 insertions(+), 33 deletions(-) create mode 100644 src/line/Makefile create mode 100644 src/line/line_message.cpp create mode 100644 src/line/line_parser.cpp create mode 100644 src/line/line_parser.h create mode 100644 src/message.h create mode 100644 src/parser.cpp create mode 100644 src/parser.h diff --git a/src/buffer.cpp b/src/buffer.cpp index 0534455..5ad6d2b 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -1,9 +1,11 @@ #include "buffer.h" +#include +#include Buffer::Buffer(){ _size = 0; _capacity = 1024; - _buf = malloc(_capacity); + _buf = (char *)malloc(_capacity); } Buffer::~Buffer(){ @@ -24,10 +26,10 @@ int Buffer::remove(int count){ return count; } -int Buffer::append(char *buf, int count){ +int Buffer::append(const char *buf, int count){ if(_size + count > _capacity){ _capacity = _size + count; - _buf = realloc(_buf, _capacity); + _buf = (char *)realloc(_buf, _capacity); } memcpy(_buf + _size, buf, count); _size += count; diff --git a/src/buffer.h b/src/buffer.h index b6c5758..56c0ea6 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1,3 +1,6 @@ +#ifndef SIM_BUFFER_H +#define SIM_BUFFER_H + class Buffer { public: @@ -8,10 +11,12 @@ class Buffer char* data(); int remove(int count); - int append(char *buf, int len); + int append(const char *buf, int len); private: int _size; char *_buf; int _capacity; }; + +#endif diff --git a/src/line/Makefile b/src/line/Makefile new file mode 100644 index 0000000..f357cbd --- /dev/null +++ b/src/line/Makefile @@ -0,0 +1,13 @@ +include ../../build_config.mk + +CFLAGS += -I ../ +OBJS=line_message.o line_parser.o + +all: $(OBJS) + +.cpp.o: + $(CXX) ${CFLAGS} -c $< -o $@ + +clean: + rm -rf *.o *.a *.out + diff --git a/src/line/line_message.cpp b/src/line/line_message.cpp new file mode 100644 index 0000000..7b16eeb --- /dev/null +++ b/src/line/line_message.cpp @@ -0,0 +1,16 @@ +#include "line_message.h" + +std::string LineMessage::text() const{ + return _text; +} + +void LineMessage::text(const std::string &s){ + _text = s; +} + +Buffer* LineMessage::encode(){ + Buffer *buf = new Buffer(); + buf->append(_text.data(), _text.size()); + buf->append("\n", 1); + return buf; +} diff --git a/src/line/line_message.h b/src/line/line_message.h index e69de29..86e86c3 100644 --- a/src/line/line_message.h +++ b/src/line/line_message.h @@ -0,0 +1,19 @@ +#ifndef SIM_LINE_MESSAGE_H +#define SIM_LINE_MESSAGE_H + +#include +#include "message.h" + +class LineMessage : public Message +{ +public: + std::string text() const; + void text(const std::string &s); + + virtual Buffer* encode(); + +private: + std::string _text; +}; + +#endif diff --git a/src/line/line_parser.cpp b/src/line/line_parser.cpp new file mode 100644 index 0000000..7c506c9 --- /dev/null +++ b/src/line/line_parser.cpp @@ -0,0 +1,24 @@ +#include "line_parser.h" + +ParseStatus LineParser::parse(Buffer *buffer, Message **msg){ + ParseStatus ret; + + const char *data = buffer->data(); + char *end = (char *)memchr(data, '\n', buffer->size()); + if(!end){ + return ret; + } + int len = end - data; + // 兼容 \r\n + if(len >= 1 && data[len - 1] == '\r'){ + len -= 1; + } + + std::string s(data, len); + LineMessage *lm = new LineMessage(); + lm->text(s); + *msg = lm; + + ret.set_ok(); + return ret; +} diff --git a/src/line/line_parser.h b/src/line/line_parser.h new file mode 100644 index 0000000..f101949 --- /dev/null +++ b/src/line/line_parser.h @@ -0,0 +1,14 @@ +#ifndef SIM_LINE_PARSER_H +#define SIM_LINE_PARSER_H + +#include +#include "parser.h" +#include "line_message.h" + +class LineParser : public Parser +{ +public: + virtual ParseStatus parse(Buffer *buffer, Message **msg); +}; + +#endif diff --git a/src/message.h b/src/message.h new file mode 100644 index 0000000..8fae43c --- /dev/null +++ b/src/message.h @@ -0,0 +1,12 @@ +#ifndef SIM_MESSAGE_H +#define SIM_MESSAGE_H + +#include "buffer.h" + +class Message +{ +public: + virtual Buffer* encode() = 0; +}; + +#endif diff --git a/src/parser.cpp b/src/parser.cpp new file mode 100644 index 0000000..646a329 --- /dev/null +++ b/src/parser.cpp @@ -0,0 +1,34 @@ +#include "parser.h" + +ParseStatus::ParseStatus(){ + _code = 0; +} + +ParseStatus::~ParseStatus(){ +} + +bool ParseStatus::ok() const{ + return _code == 1; +} + +bool ParseStatus::none() const{ + return _code == 0; +} + +bool ParseStatus::error() const{ + return _code == -1; +} + + +void ParseStatus::set_ok(){ + _code = 1; +} + +void ParseStatus::set_none(){ + _code = 0; +} + +void ParseStatus::set_error(){ + _code = -1; +} + diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..c2fa7e2 --- /dev/null +++ b/src/parser.h @@ -0,0 +1,35 @@ +#ifndef SIM_PARSER_H +#define SIM_PARSER_H + +#include "buffer.h" +#include "message.h" + +class ParseStatus; + +class Parser +{ +public: + virtual ParseStatus parse(Buffer *buffer, Message **msg) = 0; +}; + +///////////////////////////////////////// + +class ParseStatus +{ +public: + ParseStatus(); + ~ParseStatus(); + + bool ok() const; + bool none() const; + bool error() const; + + void set_ok(); + void set_none(); + void set_error(); + +private: + int _code; +}; + +#endif diff --git a/src/tcp_link.h b/src/tcp_link.h index 0e419e7..b1d604b 100644 --- a/src/tcp_link.h +++ b/src/tcp_link.h @@ -11,35 +11,6 @@ class Link virtual int send(Message &msg) = 0; }; -class Parser -{ -public: - virtual ParseStatus parse(Buffer *buffer) = 0; -}; - -class ParseStatus -{ -public: - Message* message(); - - bool ok() const; - bool none() const; - bool error() const; - - void set_ok(Message *msg); - void set_none(); - void set_error(); - -private: - int code; - Message *msg; -}; - -class Message -{ -public: - virtual Buffer* encode() = 0; -}; class Server { From 45f7a25c28bd4e0644c8e3837331f4a36dd6ef7d Mon Sep 17 00:00:00 2001 From: ideawu Date: Fri, 27 Jul 2018 19:14:57 +0800 Subject: [PATCH 07/31] update --- src/tcp_link.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/tcp_link.h b/src/tcp_link.h index b1d604b..5a4fbe3 100644 --- a/src/tcp_link.h +++ b/src/tcp_link.h @@ -16,6 +16,7 @@ class Server { public: Link* link() const; + void proc(); }; class Session @@ -23,5 +24,70 @@ class Session public: Link* link() const; Parser* parser() const; + }; +// !!! 多线程时,必须用引用计数,否则无法判断何时释放内存 +// std::shared_ptr? + +// TODO: +// 服务器循环 +while(1){ + // 处理定时器事件 + foreach(timers as timer){ + timer.invoke(); + } + + // 处理网络读事件 + foreach(in_links as link){ + lock(link){ + if(link.net_read() == -1){ + break_lock; + } + while(req = link.recv()){ + req_queue.add(req); + } + } + } + + // 处理响应 + while(link = out_links.pop()){ + lock(link){ + if(link.closed()){ + break_lock; + } + link.flush(); + } + } +} + +async proc_recv(){ + while(req = req_queue.pop()){ + resp = serv.proc(req); + lock(link){ + if(link.closed()){ + break_lock; + } + link.send(resp); + out_links.add_once(link); + } + } +} + +async business(){ + while(event = pull_event()){ + msg = generate_resp(); + lock(link){ + if(link.closed()){ + break_lock; + } + link.send(msg); + out_links.add_once(link); + } + } +} + +/* +*/ + + From de675248f317e18d8acd4d4da0e47033605c5637 Mon Sep 17 00:00:00 2001 From: ideawu Date: Mon, 30 Jul 2018 14:18:22 +0800 Subject: [PATCH 08/31] update --- src/net/Makefile | 13 +++++++ src/net/link.cpp | 39 +++++++++++++++++++++ src/net/link.h | 29 ++++++++++++++++ src/net/transport.cpp | 42 ++++++++++++++++++++++ src/net/transport.h | 30 ++++++++++++++++ src/tcp_link.h | 81 +++++++++++++------------------------------ src/util/thread.h | 31 +++++++++++++++++ 7 files changed, 209 insertions(+), 56 deletions(-) create mode 100644 src/net/Makefile create mode 100644 src/net/link.cpp create mode 100644 src/net/link.h create mode 100644 src/net/transport.cpp create mode 100644 src/net/transport.h diff --git a/src/net/Makefile b/src/net/Makefile new file mode 100644 index 0000000..76a2181 --- /dev/null +++ b/src/net/Makefile @@ -0,0 +1,13 @@ +include ../../build_config.mk + +CFLAGS += -I ../ +OBJS=link.o transport.o + +all: $(OBJS) + +.cpp.o: + $(CXX) ${CFLAGS} -c $< -o $@ + +clean: + rm -rf *.o *.a *.out + diff --git a/src/net/link.cpp b/src/net/link.cpp new file mode 100644 index 0000000..5d7dbdb --- /dev/null +++ b/src/net/link.cpp @@ -0,0 +1,39 @@ +#include "link.h" +#include + +Link::Link(){ + _status = 0; + _fd = -1; +} + +Link::~Link(){ +} + +int Link::fd() const{ + return _fd; +} + +bool Link::is_new() const{ + return _status == 0; +} + +bool Link::is_closed() const{ + return _status == 1; +} + +bool Link::is_working() const{ + return _status == 2; +} + +void Link::accept(){ + _status = 2; +} + +void Link::close(){ + if(is_closed()){ + return; + } + _status = 1; + ::close(_fd); + _fd = -1; +} diff --git a/src/net/link.h b/src/net/link.h new file mode 100644 index 0000000..c807962 --- /dev/null +++ b/src/net/link.h @@ -0,0 +1,29 @@ +#ifndef SIM_LINK_H +#define SIM_LINK_H + +class Link +{ +public: + Link(); + + int fd() const; + + bool is_new() const; + bool is_closed() const; + bool is_working() const; + + friend class Transport; + +protected: + int _status; + +private: + virtual ~Link(); + + int _fd; + + void accept(); + void close(); +}; + +#endif diff --git a/src/net/transport.cpp b/src/net/transport.cpp new file mode 100644 index 0000000..b90ec21 --- /dev/null +++ b/src/net/transport.cpp @@ -0,0 +1,42 @@ +#include "transport.h" + +Transport::Transport(){ +} + +Transport::~Transport(){ +} + +Link* Transport::listen(){ + while(1){ + _signal.wait(); + Locking l(&_mutex); + + if(!_waiting_links.empty()){ + Link *link = _waiting_links.front(); + _waiting_links.pop_front(); + return link; + } + } +} + +void Transport::accept(Link *link){ + Locking l(&_mutex); + + _working_links.insert(link); + link->accept(); +} + +void Transport::close(Link *link){ + Locking l(&_mutex); + + _working_links.erase(link); + link->close(); +} + +void Transport::setup(){ + +} + +void* Transport::run(void *arg){ + +} diff --git a/src/net/transport.h b/src/net/transport.h new file mode 100644 index 0000000..ee46213 --- /dev/null +++ b/src/net/transport.h @@ -0,0 +1,30 @@ +#ifndef SIM_TRANSPORT_H +#define SIM_TRANSPORT_H + +#include +#include +#include "util/thread.h" +#include "link.h" + +class Transport +{ +public: + Transport(); + ~Transport(); + + Link* listen(); + void accept(Link *link); + void close(Link *link); + + void setup(); + +private: + Mutex _mutex; + Semaphore _signal; + std::list _waiting_links; + std::set _working_links; + + void* run(void *arg); +}; + +#endif diff --git a/src/tcp_link.h b/src/tcp_link.h index 5a4fbe3..29794ca 100644 --- a/src/tcp_link.h +++ b/src/tcp_link.h @@ -27,67 +27,36 @@ class Session }; -// !!! 多线程时,必须用引用计数,否则无法判断何时释放内存 -// std::shared_ptr? - -// TODO: -// 服务器循环 -while(1){ - // 处理定时器事件 - foreach(timers as timer){ - timer.invoke(); - } - - // 处理网络读事件 - foreach(in_links as link){ - lock(link){ - if(link.net_read() == -1){ - break_lock; - } - while(req = link.recv()){ - req_queue.add(req); - } - } - } - - // 处理响应 - while(link = out_links.pop()){ - lock(link){ - if(link.closed()){ - break_lock; - } - link.flush(); - } +/* +Transport: + # 监控新连接,当有新连接时返回连接 id + listen() => id, status + # 接受指定的连接 + accept(id) + # 关闭连接 + close(id) + send(id, msg) + recv() => id, msg + +Thread1: + id, status = listen(); + if(status == new){ + accept(id); } -} - -async proc_recv(){ - while(req = req_queue.pop()){ - resp = serv.proc(req); - lock(link){ - if(link.closed()){ - break_lock; - } - link.send(resp); - out_links.add_once(link); - } + if(status == closed){ + close(id); } -} -async business(){ - while(event = pull_event()){ - msg = generate_resp(); - lock(link){ - if(link.closed()){ - break_lock; - } - link.send(msg); - out_links.add_once(link); - } +Thread2: + id, msg = recv(); + resp = process(msg); + if(resp){ + send(id, resp); } -} -/* +Thread3: + id, msg = do_business(); + send(id, msg); */ diff --git a/src/util/thread.h b/src/util/thread.h index 24882b0..db6b644 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -33,6 +33,37 @@ class Mutex{ } }; +class Semaphore{ +private: + pthread_mutex_t _mutex; + pthread_cond_t _cond; + int _count; +public: + Semaphore(){ + _count = 0; + pthread_mutex_init(&_mutex, NULL); + pthread_cond_init(&_cond, NULL); + } + ~Semaphore(){ + pthread_cond_destroy(&_cond); + pthread_mutex_destroy(&_mutex); + } + void wait(){ + pthread_mutex_lock(&_mutex); + while(_count == 0){ + pthread_cond_wait(&_cond, &_mutex); + } + _count--; + pthread_mutex_unlock(&_mutex); + } + void notify(){ + pthread_mutex_lock(&_mutex); + _count++; + pthread_mutex_unlock(&_mutex); + pthread_cond_signal(&_cond); + } +}; + class Locking{ private: Mutex *mutex; From 63877183535d756e29a2867d07ed1ed775efdfec Mon Sep 17 00:00:00 2001 From: ideawu Date: Mon, 30 Jul 2018 15:06:02 +0800 Subject: [PATCH 09/31] update --- src/net/Makefile | 9 +- src/net/tcp_socket.cpp | 196 +++++++++++++++++++++++++++++++++++++++++ src/net/tcp_socket.h | 52 +++++++++++ src/net/test.cpp | 15 ++++ src/net/transport.cpp | 129 +++++++++++++++++++++------ src/net/transport.h | 20 ++--- 6 files changed, 382 insertions(+), 39 deletions(-) create mode 100644 src/net/tcp_socket.cpp create mode 100644 src/net/tcp_socket.h create mode 100644 src/net/test.cpp diff --git a/src/net/Makefile b/src/net/Makefile index 76a2181..931ccd4 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,13 +1,18 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS=link.o transport.o +OBJS = fde.o link.o transport.o tcp_socket.o all: $(OBJS) - + +fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp + ${CXX} ${CFLAGS} -c fde.cpp .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ +test: + $(CXX) ${CFLAGS} test.cpp ${OBJS} ../util/libutil.a + clean: rm -rf *.o *.a *.out diff --git a/src/net/tcp_socket.cpp b/src/net/tcp_socket.cpp new file mode 100644 index 0000000..33ff595 --- /dev/null +++ b/src/net/tcp_socket.cpp @@ -0,0 +1,196 @@ +#include +#include +#include +#include +#include +#include +#include "util/log.h" +#include "tcp_socket.h" + +// namespace sim{ + +TcpSocket::TcpSocket(bool is_server){ + sock = -1; + noblock_ = false; + remote_ip[0] = '\0'; + remote_port = -1; + _buffer = new Buffer(); +} + +TcpSocket::~TcpSocket(){ + this->close(); + delete _buffer; +} + +int TcpSocket::fd() const{ + return sock; +} + +Buffer* TcpSocket::buffer() const{ + return _buffer; +} + +void TcpSocket::close(){ + if(sock >= 0){ + ::close(sock); + sock = -1; + } +} + +void TcpSocket::nodelay(bool enable){ + int opt = enable? 1 : 0; + ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); +} + +void TcpSocket::keepalive(bool enable){ + int opt = enable? 1 : 0; + ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); +} + +void TcpSocket::noblock(bool enable){ + noblock_ = enable; + if(enable){ + ::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR); + }else{ + ::fcntl(sock, F_SETFL, O_RDWR); + } +} + +TcpSocket* TcpSocket::connect(const std::string &ip, int port){ + return connect(ip.c_str(), port); +} + +TcpSocket* TcpSocket::connect(const char *ip, int port){ + TcpSocket *link; + int sock = -1; + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short)port); + inet_pton(AF_INET, ip, &addr.sin_addr); + + if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){ + goto sock_err; + } + if(::connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){ + goto sock_err; + } + + //log_debug("fd: %d, connect to %s:%d", sock, ip, port); + link = new TcpSocket(); + link->sock = sock; + link->keepalive(true); + return link; +sock_err: + //log_debug("connect to %s:%d failed: %s", ip, port, strerror(errno)); + if(sock >= 0){ + ::close(sock); + } + return NULL; +} + +TcpSocket* TcpSocket::listen(const std::string &ip, int port){ + return listen(ip.c_str(), port); +} + +TcpSocket* TcpSocket::listen(const char *ip, int port){ + TcpSocket *link; + int sock = -1; + + int opt = 1; + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons((short)port); + inet_pton(AF_INET, ip, &addr.sin_addr); + + if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){ + goto sock_err; + } + if(::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){ + goto sock_err; + } + if(::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){ + goto sock_err; + } + if(::listen(sock, 1024) == -1){ + goto sock_err; + } + //log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port); + + link = new TcpSocket(true); + link->sock = sock; + snprintf(link->remote_ip, sizeof(link->remote_ip), "%s", ip); + link->remote_port = port; + return link; +sock_err: + //log_debug("listen %s:%d failed: %s", ip, port, strerror(errno)); + if(sock >= 0){ + ::close(sock); + } + return NULL; +} + +TcpSocket* TcpSocket::accept(){ + TcpSocket *link; + int client_sock; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + + while((client_sock = ::accept(sock, (struct sockaddr *)&addr, &addrlen)) == -1){ + if(errno != EINTR){ + //log_error("socket %d accept failed: %s", sock, strerror(errno)); + return NULL; + } + } + + struct linger opt = {1, 0}; + int ret = ::setsockopt(client_sock, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof(opt)); + if (ret != 0) { + //log_error("socket %d set linger failed: %s", client_sock, strerror(errno)); + } + + link = new TcpSocket(); + link->sock = client_sock; + link->keepalive(true); + inet_ntop(AF_INET, &addr.sin_addr, link->remote_ip, sizeof(link->remote_ip)); + link->remote_port = ntohs(addr.sin_port); + return link; +} + +int TcpSocket::net_read(){ + int ret = 0; + char buf[8 * 1024]; + int want = sizeof(buf); + while(1){ + // test + //want = 1; + int len = ::read(sock, buf, want); + if(len == -1){ + if(errno == EINTR){ + continue; + }else if(errno == EWOULDBLOCK){ + break; + }else{ + //log_debug("fd: %d, read: -1, want: %d, error: %s", sock, want, strerror(errno)); + return -1; + } + }else{ + //log_debug("fd: %d, want=%d, read: %d", sock, want, len); + if(len == 0){ + return 0; + } + ret += len; + + _buffer->append(buf, len); + } + if(!noblock_){ + break; + } + } + //log_debug("read %d", ret); + return ret; +} + +// }; // namespace sim diff --git a/src/net/tcp_socket.h b/src/net/tcp_socket.h new file mode 100644 index 0000000..629c1de --- /dev/null +++ b/src/net/tcp_socket.h @@ -0,0 +1,52 @@ +#ifndef SIM_TCP_SOCKET_H_ +#define SIM_TCP_SOCKET_H_ + +#include +#include +#include +#include +#include +#include +#include "util/buffer.h" + +// namespace sim{ + +class TcpSocket{ +public: + char remote_ip[INET_ADDRSTRLEN]; + int remote_port; + + double create_time; + double active_time; + + ~TcpSocket(); + void close(); + void nodelay(bool enable=true); + void noblock(bool enable=true); + void keepalive(bool enable=true); + + int fd() const; + Buffer* buffer() const; + + int net_read(); + // int net_write(); + + static TcpSocket* connect(const char *ip, int port); + static TcpSocket* connect(const std::string &ip, int port); + static TcpSocket* listen(const char *ip, int port); + static TcpSocket* listen(const std::string &ip, int port); + TcpSocket* accept(); + +private: + int sock; + bool noblock_; + Buffer* _buffer; + + TcpSocket(bool is_server=false); + +}; + + +// }; // namespace sim + +#endif diff --git a/src/net/test.cpp b/src/net/test.cpp new file mode 100644 index 0000000..3527e91 --- /dev/null +++ b/src/net/test.cpp @@ -0,0 +1,15 @@ +#include "transport.h" +#include "util/log.h" + +// using namespace sim; + +int main(int argc, char **argv){ + Transport *trans = new Transport(); + trans->setup(); + log_debug("transport setup"); + + while(1){ + usleep(100 * 1000); + } + return 0; +} diff --git a/src/net/transport.cpp b/src/net/transport.cpp index b90ec21..3c48ab2 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -1,42 +1,117 @@ #include "transport.h" +#include "util/log.h" +#include "fde.h" +#include "tcp_socket.h" -Transport::Transport(){ -} +using namespace sim; -Transport::~Transport(){ -} +// #define TICK_INTERVAL 100 // ms +// volatile bool quit = false; +// volatile uint32_t g_ticks = 0; +// +// void signal_handler(int sig){ +// switch(sig){ +// case SIGTERM: +// case SIGINT:{ +// quit = true; +// break; +// } +// case SIGALRM:{ +// g_ticks ++; +// break; +// } +// } +// } -Link* Transport::listen(){ - while(1){ - _signal.wait(); - Locking l(&_mutex); - - if(!_waiting_links.empty()){ - Link *link = _waiting_links.front(); - _waiting_links.pop_front(); - return link; - } - } -} -void Transport::accept(Link *link){ - Locking l(&_mutex); - - _working_links.insert(link); - link->accept(); +Transport::Transport(){ } -void Transport::close(Link *link){ - Locking l(&_mutex); - - _working_links.erase(link); - link->close(); +Transport::~Transport(){ } +// Link* Transport::listen(){ +// // while(1){ +// // // _signal.wait(); +// // // Locking l(&_mutex); +// // +// // if(!_waiting_links.empty()){ +// // Link *link = _waiting_links.front(); +// // _waiting_links.pop_front(); +// // return link; +// // } +// // } +// } +// +// void Transport::accept(Link *link){ +// // Locking l(&_mutex); +// +// // _working_links.insert(link); +// // link->accept(); +// } +// +// void Transport::close(Link *link){ +// // Locking l(&_mutex); +// +// // _working_links.erase(link); +// // link->close(); +// } + void Transport::setup(){ - + pthread_t tid; + int err = pthread_create(&tid, NULL, &Transport::run, this); + if(err != 0){ + log_error("can't create thread: %s", strerror(err)); + } } void* Transport::run(void *arg){ +// Transport *trans = (Transport *)arg; +// signal(SIGPIPE, SIG_IGN); +// signal(SIGINT, signal_handler); +// signal(SIGTERM, signal_handler); +// #ifndef __CYGWIN__ +// signal(SIGALRM, signal_handler); +// { +// struct itimerval tv; +// tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); +// tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; +// tv.it_value.tv_sec = 1; +// tv.it_value.tv_usec = 0; +// setitimer(ITIMER_REAL, &tv, NULL); +// } +// #endif + + Fdevents *fdes; + const Fdevents::events_t *events; + fdes = new Fdevents(); + + TcpSocket *tcp_serv = TcpSocket::listen("127.0.0.1", 9000); + fdes->set(tcp_serv->fd(), FDEVENT_IN, 0, tcp_serv); + log_debug(""); + while(1){ + log_debug(""); + events = fdes->wait(500); + + for(int i=0; i<(int)events->size(); i++){ + const Fdevent *fde = events->at(i); + if(fde->data.ptr == tcp_serv){ + TcpSocket *conn = tcp_serv->accept(); + if(conn){ + log_debug("new connection from %s:%d, fd: %d", + conn->remote_ip, conn->remote_port, conn->fd()); + fdes->set(conn->fd(), FDEVENT_IN, 1, conn); + }else{ + log_debug("accept return NULL"); + } + }else{ + TcpSocket *conn = (TcpSocket *)fde->data.ptr; + log_debug("read from connection %s:%d, fd: %d", + conn->remote_ip, conn->remote_port, conn->fd()); + } + } + + } + return NULL; } diff --git a/src/net/transport.h b/src/net/transport.h index ee46213..381ac4e 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -3,8 +3,8 @@ #include #include -#include "util/thread.h" -#include "link.h" +// #include "util/thread.h" +// #include "link.h" class Transport { @@ -12,19 +12,19 @@ class Transport Transport(); ~Transport(); - Link* listen(); - void accept(Link *link); - void close(Link *link); + // Link* listen(); + // void accept(Link *link); + // void close(Link *link); void setup(); private: - Mutex _mutex; - Semaphore _signal; - std::list _waiting_links; - std::set _working_links; + // Mutex _mutex; + // Semaphore _signal; + // std::list _waiting_links; + // std::set _working_links; - void* run(void *arg); + static void* run(void *arg); }; #endif From fd6f0a5822cb8fc6582303ff19b4dcd5c8ee27f8 Mon Sep 17 00:00:00 2001 From: ideawu Date: Mon, 30 Jul 2018 15:06:19 +0800 Subject: [PATCH 10/31] update --- src/link-.cc | 240 -------------------------------------- src/link-.h | 70 ----------- src/util/Makefile | 14 +++ src/{ => util}/buffer.cpp | 0 src/{ => util}/buffer.h | 0 5 files changed, 14 insertions(+), 310 deletions(-) delete mode 100644 src/link-.cc delete mode 100644 src/link-.h create mode 100644 src/util/Makefile rename src/{ => util}/buffer.cpp (100%) rename src/{ => util}/buffer.h (100%) diff --git a/src/link-.cc b/src/link-.cc deleted file mode 100644 index 1020b5b..0000000 --- a/src/link-.cc +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "util/log.h" -#include "link.h" - -namespace sim{ - -Link::Link(bool is_server){ - sock = -1; - noblock_ = false; - error_ = false; - remote_ip[0] = '\0'; - remote_port = -1; -} - -Link::~Link(){ - this->close(); -} - -void Link::close(){ - if(sock >= 0){ - ::close(sock); - sock = -1; - } -} - -void Link::nodelay(bool enable){ - int opt = enable? 1 : 0; - ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); -} - -void Link::keepalive(bool enable){ - int opt = enable? 1 : 0; - ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); -} - -void Link::noblock(bool enable){ - noblock_ = enable; - if(enable){ - ::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR); - }else{ - ::fcntl(sock, F_SETFL, O_RDWR); - } -} - -Link* Link::connect(const std::string &ip, int port){ - return connect(ip.c_str(), port); -} - -Link* Link::connect(const char *ip, int port){ - Link *link; - int sock = -1; - - struct sockaddr_in addr; - bzero(&addr, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons((short)port); - inet_pton(AF_INET, ip, &addr.sin_addr); - - if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){ - goto sock_err; - } - if(::connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){ - goto sock_err; - } - - //log_debug("fd: %d, connect to %s:%d", sock, ip, port); - link = new Link(); - link->sock = sock; - link->keepalive(true); - return link; -sock_err: - //log_debug("connect to %s:%d failed: %s", ip, port, strerror(errno)); - if(sock >= 0){ - ::close(sock); - } - return NULL; -} - -Link* Link::listen(const std::string &ip, int port){ - return listen(ip.c_str(), port); -} - -Link* Link::listen(const char *ip, int port){ - Link *link; - int sock = -1; - - int opt = 1; - struct sockaddr_in addr; - bzero(&addr, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons((short)port); - inet_pton(AF_INET, ip, &addr.sin_addr); - - if((sock = ::socket(AF_INET, SOCK_STREAM, 0)) == -1){ - goto sock_err; - } - if(::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){ - goto sock_err; - } - if(::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1){ - goto sock_err; - } - if(::listen(sock, 1024) == -1){ - goto sock_err; - } - //log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port); - - link = new Link(true); - link->sock = sock; - snprintf(link->remote_ip, sizeof(link->remote_ip), "%s", ip); - link->remote_port = port; - return link; -sock_err: - //log_debug("listen %s:%d failed: %s", ip, port, strerror(errno)); - if(sock >= 0){ - ::close(sock); - } - return NULL; -} - -Link* Link::accept(){ - Link *link; - int client_sock; - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); - - while((client_sock = ::accept(sock, (struct sockaddr *)&addr, &addrlen)) == -1){ - if(errno != EINTR){ - //log_error("socket %d accept failed: %s", sock, strerror(errno)); - return NULL; - } - } - - struct linger opt = {1, 0}; - int ret = ::setsockopt(client_sock, SOL_SOCKET, SO_LINGER, (void *)&opt, sizeof(opt)); - if (ret != 0) { - //log_error("socket %d set linger failed: %s", client_sock, strerror(errno)); - } - - link = new Link(); - link->sock = client_sock; - link->keepalive(true); - inet_ntop(AF_INET, &addr.sin_addr, link->remote_ip, sizeof(link->remote_ip)); - link->remote_port = ntohs(addr.sin_port); - return link; -} - -int Link::read(){ - int ret = 0; - char buf[16 * 1024]; - int want = sizeof(buf); - while(1){ - // test - //want = 1; - int len = ::read(sock, buf, want); - if(len == -1){ - if(errno == EINTR){ - continue; - }else if(errno == EWOULDBLOCK){ - break; - }else{ - //log_debug("fd: %d, read: -1, want: %d, error: %s", sock, want, strerror(errno)); - return -1; - } - }else{ - //log_debug("fd: %d, want=%d, read: %d", sock, want, len); - if(len == 0){ - return 0; - } - ret += len; - decoder_.push(buf, len); - } - if(!noblock_){ - break; - } - } - //log_debug("read %d", ret); - return ret; -} - -int Link::write(){ - int ret = 0; - int want; - while((want = output.size()) > 0){ - // test - //want = 1; - int len = ::write(sock, output.data(), want); - if(len == -1){ - if(errno == EINTR){ - continue; - }else if(errno == EWOULDBLOCK){ - break; - }else{ - //log_debug("fd: %d, write: -1, error: %s", sock, strerror(errno)); - return -1; - } - }else{ - //log_info("fd: %d, want: %d, write: %d", sock, want, len); - if(len == 0){ - // ? - break; - } - ret += len; - output = std::string(output.data() + len, output.size() - len); - } - if(!noblock_){ - break; - } - } - return ret; -} - -int Link::flush(){ - int len = 0; - while(!output.empty()){ - int ret = this->write(); - if(ret == -1){ - return -1; - } - len += ret; - } - return len; -} - -int Link::recv(Message *msg){ - return decoder_.parse(msg); -} - -int Link::send(const Message &msg){ - std::string s = msg.encode(); - output.append(s); - return (int)s.size(); -} - -}; // namespace sim diff --git a/src/link-.h b/src/link-.h deleted file mode 100644 index dbabb83..0000000 --- a/src/link-.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef SIM_LINK_H_ -#define SIM_LINK_H_ - -#include -#include -#include -#include -#include -#include -#include "decoder.h" - -namespace sim{ - -class Link{ -private: - int sock; - bool noblock_; - bool error_; - Decoder decoder_; - Link(bool is_server=false); - - // TODO: max_recv_buf_size, max_send_buf_size -public: - std::string output; - - char remote_ip[INET_ADDRSTRLEN]; - int remote_port; - - double create_time; - double active_time; - - ~Link(); - void close(); - void nodelay(bool enable=true); - // noblock(true) is supposed to corperate with IO Multiplex, - // otherwise, flush() may cause a lot unneccessary write calls. - void noblock(bool enable=true); - void keepalive(bool enable=true); - - int fd() const{ - return sock; - } - bool error() const{ - return error_; - } - void mark_error(){ - error_ = true; - } - - static Link* connect(const char *ip, int port); - static Link* connect(const std::string &ip, int port); - static Link* listen(const char *ip, int port); - static Link* listen(const std::string &ip, int port); - Link* accept(); - - // read network data info buffer - int read(); - int write(); - // flush buffered data to network - // REQUIRES: nonblock - int flush(); - - int recv(Message *msg); - int send(const Message &msg); -}; - - -}; // namespace sim - -#endif diff --git a/src/util/Makefile b/src/util/Makefile new file mode 100644 index 0000000..c45126d --- /dev/null +++ b/src/util/Makefile @@ -0,0 +1,14 @@ +include ../../build_config.mk + +CFLAGS += -I ../ +OBJS = log.o buffer.o + +all: ${OBJS} + ar -cru ./libutil.a ${OBJS} + +.cpp.o: + $(CXX) ${CFLAGS} -c $< -o $@ + +clean: + rm -rf *.o *.a *.out + diff --git a/src/buffer.cpp b/src/util/buffer.cpp similarity index 100% rename from src/buffer.cpp rename to src/util/buffer.cpp diff --git a/src/buffer.h b/src/util/buffer.h similarity index 100% rename from src/buffer.h rename to src/util/buffer.h From 4781137a3d17593250c336018b3e2248d104ff90 Mon Sep 17 00:00:00 2001 From: ideawu Date: Mon, 30 Jul 2018 19:46:45 +0800 Subject: [PATCH 11/31] update --- src/net/Makefile | 4 +- src/net/fde_epoll.cpp | 2 + src/net/fde_select.cpp | 2 + src/net/{tcp_socket.cpp => tcp_link.cpp} | 43 +++--- src/net/{tcp_socket.h => tcp_link.h} | 20 +-- src/net/test.cpp | 40 +++++- src/net/transport.cpp | 172 +++++++++++++---------- src/net/transport.h | 81 +++++++++-- src/util/thread.h | 108 ++++++++++++-- 9 files changed, 346 insertions(+), 126 deletions(-) rename src/net/{tcp_socket.cpp => tcp_link.cpp} (82%) rename src/net/{tcp_socket.h => tcp_link.h} (64%) diff --git a/src/net/Makefile b/src/net/Makefile index 931ccd4..e45c107 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,7 +1,7 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o link.o transport.o tcp_socket.o +OBJS = fde.o tcp_link.o transport.o all: $(OBJS) @@ -11,6 +11,8 @@ fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp $(CXX) ${CFLAGS} -c $< -o $@ test: + make clean + make $(CXX) ${CFLAGS} test.cpp ${OBJS} ../util/libutil.a clean: diff --git a/src/net/fde_epoll.cpp b/src/net/fde_epoll.cpp index bddc4ec..b94fc1f 100644 --- a/src/net/fde_epoll.cpp +++ b/src/net/fde_epoll.cpp @@ -60,6 +60,8 @@ int Fdevents::del(int fd){ } struct Fdevent *fde = get_fde(fd); + fde->data.num = 0; + fde->data.ptr = NULL; fde->s_flags = FDEVENT_NONE; return 0; } diff --git a/src/net/fde_select.cpp b/src/net/fde_select.cpp index 8a18ff0..8349c03 100644 --- a/src/net/fde_select.cpp +++ b/src/net/fde_select.cpp @@ -53,6 +53,8 @@ int Fdevents::del(int fd){ FD_CLR(fd, &writeset); struct Fdevent *fde = get_fde(fd); + fde->data.num = 0; + fde->data.ptr = NULL; fde->s_flags = FDEVENT_NONE; while(maxfd >= 0 && this->events[maxfd]->s_flags == 0){ maxfd --; diff --git a/src/net/tcp_socket.cpp b/src/net/tcp_link.cpp similarity index 82% rename from src/net/tcp_socket.cpp rename to src/net/tcp_link.cpp index 33ff595..492c178 100644 --- a/src/net/tcp_socket.cpp +++ b/src/net/tcp_link.cpp @@ -5,11 +5,11 @@ #include #include #include "util/log.h" -#include "tcp_socket.h" +#include "tcp_link.h" // namespace sim{ -TcpSocket::TcpSocket(bool is_server){ +TcpLink::TcpLink(bool is_server){ sock = -1; noblock_ = false; remote_ip[0] = '\0'; @@ -17,37 +17,38 @@ TcpSocket::TcpSocket(bool is_server){ _buffer = new Buffer(); } -TcpSocket::~TcpSocket(){ +TcpLink::~TcpLink(){ this->close(); delete _buffer; } -int TcpSocket::fd() const{ +int TcpLink::fd() const{ return sock; } -Buffer* TcpSocket::buffer() const{ +Buffer* TcpLink::buffer() const{ return _buffer; } -void TcpSocket::close(){ +void TcpLink::close(){ if(sock >= 0){ ::close(sock); sock = -1; } + _status = -1; } -void TcpSocket::nodelay(bool enable){ +void TcpLink::nodelay(bool enable){ int opt = enable? 1 : 0; ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); } -void TcpSocket::keepalive(bool enable){ +void TcpLink::keepalive(bool enable){ int opt = enable? 1 : 0; ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); } -void TcpSocket::noblock(bool enable){ +void TcpLink::noblock(bool enable){ noblock_ = enable; if(enable){ ::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR); @@ -56,12 +57,12 @@ void TcpSocket::noblock(bool enable){ } } -TcpSocket* TcpSocket::connect(const std::string &ip, int port){ +TcpLink* TcpLink::connect(const std::string &ip, int port){ return connect(ip.c_str(), port); } -TcpSocket* TcpSocket::connect(const char *ip, int port){ - TcpSocket *link; +TcpLink* TcpLink::connect(const char *ip, int port){ + TcpLink *link; int sock = -1; struct sockaddr_in addr; @@ -78,7 +79,7 @@ TcpSocket* TcpSocket::connect(const char *ip, int port){ } //log_debug("fd: %d, connect to %s:%d", sock, ip, port); - link = new TcpSocket(); + link = new TcpLink(); link->sock = sock; link->keepalive(true); return link; @@ -90,12 +91,12 @@ TcpSocket* TcpSocket::connect(const char *ip, int port){ return NULL; } -TcpSocket* TcpSocket::listen(const std::string &ip, int port){ +TcpLink* TcpLink::listen(const std::string &ip, int port){ return listen(ip.c_str(), port); } -TcpSocket* TcpSocket::listen(const char *ip, int port){ - TcpSocket *link; +TcpLink* TcpLink::listen(const char *ip, int port){ + TcpLink *link; int sock = -1; int opt = 1; @@ -119,7 +120,7 @@ TcpSocket* TcpSocket::listen(const char *ip, int port){ } //log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port); - link = new TcpSocket(true); + link = new TcpLink(true); link->sock = sock; snprintf(link->remote_ip, sizeof(link->remote_ip), "%s", ip); link->remote_port = port; @@ -132,8 +133,8 @@ TcpSocket* TcpSocket::listen(const char *ip, int port){ return NULL; } -TcpSocket* TcpSocket::accept(){ - TcpSocket *link; +TcpLink* TcpLink::accept(){ + TcpLink *link; int client_sock; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); @@ -151,7 +152,7 @@ TcpSocket* TcpSocket::accept(){ //log_error("socket %d set linger failed: %s", client_sock, strerror(errno)); } - link = new TcpSocket(); + link = new TcpLink(); link->sock = client_sock; link->keepalive(true); inet_ntop(AF_INET, &addr.sin_addr, link->remote_ip, sizeof(link->remote_ip)); @@ -159,7 +160,7 @@ TcpSocket* TcpSocket::accept(){ return link; } -int TcpSocket::net_read(){ +int TcpLink::net_read(){ int ret = 0; char buf[8 * 1024]; int want = sizeof(buf); diff --git a/src/net/tcp_socket.h b/src/net/tcp_link.h similarity index 64% rename from src/net/tcp_socket.h rename to src/net/tcp_link.h index 629c1de..8498cf9 100644 --- a/src/net/tcp_socket.h +++ b/src/net/tcp_link.h @@ -11,7 +11,7 @@ // namespace sim{ -class TcpSocket{ +class TcpLink{ public: char remote_ip[INET_ADDRSTRLEN]; int remote_port; @@ -19,31 +19,33 @@ class TcpSocket{ double create_time; double active_time; - ~TcpSocket(); + ~TcpLink(); void close(); void nodelay(bool enable=true); void noblock(bool enable=true); void keepalive(bool enable=true); + int id() const; int fd() const; Buffer* buffer() const; int net_read(); // int net_write(); - static TcpSocket* connect(const char *ip, int port); - static TcpSocket* connect(const std::string &ip, int port); - static TcpSocket* listen(const char *ip, int port); - static TcpSocket* listen(const std::string &ip, int port); - TcpSocket* accept(); + static TcpLink* connect(const char *ip, int port); + static TcpLink* connect(const std::string &ip, int port); + static TcpLink* listen(const char *ip, int port); + static TcpLink* listen(const std::string &ip, int port); + TcpLink* accept(); private: + int _id; int sock; bool noblock_; + int _status; Buffer* _buffer; - TcpSocket(bool is_server=false); - + TcpLink(bool is_server=false); }; diff --git a/src/net/test.cpp b/src/net/test.cpp index 3527e91..758325d 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -3,12 +3,50 @@ // using namespace sim; +#define TICK_INTERVAL 100 // ms +volatile bool quit = false; + +void signal_handler(int sig){ + switch(sig){ + case SIGTERM: + case SIGINT:{ + quit = true; + break; + } + case SIGALRM:{ + break; + } + } +} + int main(int argc, char **argv){ + signal(SIGPIPE, SIG_IGN); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); +#ifndef __CYGWIN__ + signal(SIGALRM, signal_handler); + { + struct itimerval tv; + tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); + tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; + tv.it_value.tv_sec = 1; + tv.it_value.tv_usec = 0; + setitimer(ITIMER_REAL, &tv, NULL); + } +#endif + Transport *trans = new Transport(); trans->setup(); log_debug("transport setup"); - while(1){ + TcpLink *link = trans->wait(); + if(link->is_new()){ + trans->read(link); + }else if(link->is_closing()){ + trans->close(link); + } + + while(!quit){ usleep(100 * 1000); } return 0; diff --git a/src/net/transport.cpp b/src/net/transport.cpp index 3c48ab2..c19fce4 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -1,28 +1,5 @@ #include "transport.h" #include "util/log.h" -#include "fde.h" -#include "tcp_socket.h" - -using namespace sim; - -// #define TICK_INTERVAL 100 // ms -// volatile bool quit = false; -// volatile uint32_t g_ticks = 0; -// -// void signal_handler(int sig){ -// switch(sig){ -// case SIGTERM: -// case SIGINT:{ -// quit = true; -// break; -// } -// case SIGALRM:{ -// g_ticks ++; -// break; -// } -// } -// } - Transport::Transport(){ } @@ -30,34 +7,86 @@ Transport::Transport(){ Transport::~Transport(){ } -// Link* Transport::listen(){ +// TcpLink* Transport::wait(){ // // while(1){ -// // // _signal.wait(); -// // // Locking l(&_mutex); +// // _signal.wait(); +// // Locking l(&_mutex); // // // // if(!_waiting_links.empty()){ -// // Link *link = _waiting_links.front(); +// // TcpLink *link = _waiting_links.front(); // // _waiting_links.pop_front(); // // return link; // // } // // } // } -// -// void Transport::accept(Link *link){ -// // Locking l(&_mutex); -// -// // _working_links.insert(link); -// // link->accept(); -// } -// -// void Transport::close(Link *link){ -// // Locking l(&_mutex); -// -// // _working_links.erase(link); -// // link->close(); -// } + +void Transport::accept(int id){ + this->_accept_ids.push(id); +} + +void Transport::close(int id){ + this->_close_ids.push(id); + + Locking l(&_mutex); + if(_working_links.find(id) != _working_links.end()){ + TcpLink *link = _working_links[id]; + _working_links.erase(id); + _closing_links[id] = link; + } +} + +void Transport::handle_new_link(TcpLink *link){ + log_debug("new link from %s:%d, fd: %d", link->remote_ip, link->remote_port, link->fd()); + + Locking l(&_mutex); + int id = link->id(); + _working_links[id] = link; + + this->_events.push(LinkEvent::new_link(link)); +} + +void Transport::handle_close_link(TcpLink *link){ + log_debug("closing link %s:%d", link->remote_ip, link->remote_port); + + Locking l(&_mutex); + int id = link->id(); + _working_links.erase(id); + _closing_links[id] = link; + + this->_events.push(LinkEvent::close_link(link)); +} + +void Transport::handle_accept_id(){ + int id; + _accept_ids.pop(&id); + + Locking l(&_mutex); + if(_working_links.find(id) != _working_links.end()){ + TcpLink *link = _working_links[id]; + _fdes->set(link->fd(), FDEVENT_IN, 1, link); + } +} + +void Transport::handle_close_id(){ + int id; + _close_ids.pop(&id); + + Locking l(&_mutex); + if(_closing_links.find(id) != _closing_links.end()){ + TcpLink *link = _closing_links[id]; + _closing_links.erase(id); + + _fdes->del(link->fd()); + delete link; + } +} void Transport::setup(){ + _fdes = new Fdevents(); + + _fdes->set(_accept_ids.fd(), FDEVENT_IN, 0, &_accept_ids); + _fdes->set(_close_ids.fd(), FDEVENT_IN, 0, &_close_ids); + pthread_t tid; int err = pthread_create(&tid, NULL, &Transport::run, this); if(err != 0){ @@ -66,52 +95,45 @@ void Transport::setup(){ } void* Transport::run(void *arg){ -// Transport *trans = (Transport *)arg; -// signal(SIGPIPE, SIG_IGN); -// signal(SIGINT, signal_handler); -// signal(SIGTERM, signal_handler); -// #ifndef __CYGWIN__ -// signal(SIGALRM, signal_handler); -// { -// struct itimerval tv; -// tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); -// tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; -// tv.it_value.tv_sec = 1; -// tv.it_value.tv_usec = 0; -// setitimer(ITIMER_REAL, &tv, NULL); -// } -// #endif - - Fdevents *fdes; + Transport *trans = (Transport *)arg; const Fdevents::events_t *events; - fdes = new Fdevents(); + + TcpLink *tcp_serv = TcpLink::listen("127.0.0.1", 8000); + if(!tcp_serv){ + log_error("failed to listen at 127.0.0.1:8000, %s", strerror(errno)); + } - TcpSocket *tcp_serv = TcpSocket::listen("127.0.0.1", 9000); - fdes->set(tcp_serv->fd(), FDEVENT_IN, 0, tcp_serv); + trans->_fdes->set(tcp_serv->fd(), FDEVENT_IN, 0, tcp_serv); - log_debug(""); while(1){ - log_debug(""); - events = fdes->wait(500); + events = trans->_fdes->wait(500); for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); - if(fde->data.ptr == tcp_serv){ - TcpSocket *conn = tcp_serv->accept(); - if(conn){ - log_debug("new connection from %s:%d, fd: %d", - conn->remote_ip, conn->remote_port, conn->fd()); - fdes->set(conn->fd(), FDEVENT_IN, 1, conn); + if(fde->data.ptr == &trans->_accept_ids){ + trans->handle_accept_id(); + }else if(fde->data.ptr == &trans->_close_ids){ + trans->handle_close_id(); + }else if(fde->data.ptr == tcp_serv){ + TcpLink *link = tcp_serv->accept(); + if(link){ + trans->handle_new_link(link); }else{ - log_debug("accept return NULL"); + log_error("accept return NULL"); } }else{ - TcpSocket *conn = (TcpSocket *)fde->data.ptr; - log_debug("read from connection %s:%d, fd: %d", - conn->remote_ip, conn->remote_port, conn->fd()); + TcpLink *link = (TcpLink *)fde->data.ptr; + if(link){ // 防止已经被 fde_del + log_debug("read %s:%d, fd: %d", link->remote_ip, link->remote_port, link->fd()); + int ret = link->net_read(); + if(ret <= 0){ + trans->handle_close_link(link); + }else{ + // + } + } } } - } return NULL; } diff --git a/src/net/transport.h b/src/net/transport.h index 381ac4e..be09c15 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -1,10 +1,53 @@ #ifndef SIM_TRANSPORT_H #define SIM_TRANSPORT_H -#include -#include -// #include "util/thread.h" -// #include "link.h" +#include +#include "util/thread.h" +#include "tcp_link.h" +#include "fde.h" + +using namespace sim; + + +class LinkEvent +{ +public: + LinkEvent(){ + _status = 0; + } + LinkEvent(int id, int status){ + _id = id; + _status = status; + } + + int id() const{ + return _id; + } + bool is_new() const{ + return _status == 0; + } + bool is_close() const{ + return _status == 1; + } + bool is_read() const{ + return _status == 2; + } + + static LinkEvent new_link(TcpLink *link){ + return LinkEvent(link->id(), 0); + } + static LinkEvent close_link(TcpLink *link){ + return LinkEvent(link->id(), 1); + } + static LinkEvent read_link(TcpLink *link){ + return LinkEvent(link->id(), 2); + } + + friend class Transport; +private: + int _id; + int _status; +}; class Transport { @@ -12,17 +55,33 @@ class Transport Transport(); ~Transport(); - // Link* listen(); - // void accept(Link *link); - // void close(Link *link); + LinkEvent wait(); + + void accept(int id); + void close(int id); + + // Message* recv(int id); + // void send(int id, Message *msg); void setup(); private: - // Mutex _mutex; - // Semaphore _signal; - // std::list _waiting_links; - // std::set _working_links; + Mutex _mutex; + + std::map _working_links; + std::map _closing_links; + + Queue _events; + + Channel _accept_ids; + Channel _close_ids; + + void handle_new_link(TcpLink *link); + void handle_close_link(TcpLink *link); + void handle_accept_id(); + void handle_close_id(); + + Fdevents *_fdes; static void* run(void *arg); }; diff --git a/src/util/thread.h b/src/util/thread.h index db6b644..5e6a0a1 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -81,17 +81,109 @@ class Locking{ }; +// Thread safe queue +template +class Queue{ + private: + pthread_cond_t cond; + pthread_mutex_t mutex; + std::queue items; + public: + Queue(); + ~Queue(); + + bool empty(); + int size(); + int push(const T item); + // TODO: with timeout + int pop(T *data); +}; + +template +Queue::Queue(){ + pthread_cond_init(&cond, NULL); + pthread_mutex_init(&mutex, NULL); +} + +template +Queue::~Queue(){ + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mutex); +} + +template +bool Queue::empty(){ + bool ret = false; + if(pthread_mutex_lock(&mutex) != 0){ + return -1; + } + ret = items.empty(); + pthread_mutex_unlock(&mutex); + return ret; +} + +template +int Queue::size(){ + int ret = -1; + if(pthread_mutex_lock(&mutex) != 0){ + return -1; + } + ret = items.size(); + pthread_mutex_unlock(&mutex); + return ret; +} + +template +int Queue::push(const T item){ + if(pthread_mutex_lock(&mutex) != 0){ + return -1; + } + { + items.push(item); + } + pthread_mutex_unlock(&mutex); + pthread_cond_signal(&cond); + return 1; +} + +template +int Queue::pop(T *data){ + if(pthread_mutex_lock(&mutex) != 0){ + return -1; + } + { + // 必须放在循环中, 因为 pthread_cond_wait 可能抢不到锁而被其它处理了 + while(items.empty()){ + //fprintf(stderr, "%d wait\n", pthread_self()); + if(pthread_cond_wait(&cond, &mutex) != 0){ + //fprintf(stderr, "%s %d -1!\n", __FILE__, __LINE__); + return -1; + } + //fprintf(stderr, "%d wait 2\n", pthread_self()); + } + *data = items.front(); + //fprintf(stderr, "%d job: %d\n", pthread_self(), (int)*data); + items.pop(); + } + if(pthread_mutex_unlock(&mutex) != 0){ + //fprintf(stderr, "error!\n"); + return -1; + } + //fprintf(stderr, "%d wait end 2, job: %d\n", pthread_self(), (int)*data); + return 1; +} + // Selectable queue, multi writers, single reader template -class SelectableQueue{ +class Channel{ private: int fds[2]; public: Mutex mutex; std::queue items; - SelectableQueue(); - ~SelectableQueue(); + Channel(); + ~Channel(); int fd(){ return fds[0]; } @@ -104,26 +196,26 @@ class SelectableQueue{ template -SelectableQueue::SelectableQueue(){ +Channel::Channel(){ if(pipe(fds) == -1){ exit(0); } } template -SelectableQueue::~SelectableQueue(){ +Channel::~Channel(){ close(fds[0]); close(fds[1]); } template -int SelectableQueue::size(){ +int Channel::size(){ Locking l(&mutex); return items.size(); } template -int SelectableQueue::push(const T item){ +int Channel::push(const T item){ Locking l(&mutex); items.push(item); if(::write(fds[1], "1", 1) == -1){ @@ -133,7 +225,7 @@ int SelectableQueue::push(const T item){ } template -int SelectableQueue::pop(T *data){ +int Channel::pop(T *data){ int n, ret = 1; char buf[1]; From 61b1d735209dad5667f5eaf17714e9978c2f4eb0 Mon Sep 17 00:00:00 2001 From: ideawu Date: Mon, 30 Jul 2018 20:44:52 +0800 Subject: [PATCH 12/31] update --- src/net/tcp_link.cpp | 7 +++++ src/net/test.cpp | 39 +++++++++++++------------ src/net/transport.cpp | 19 +++++------- src/net/transport.h | 8 +++-- src/util/thread.h | 68 ++++++++++++++++++++++++++++++++++--------- 5 files changed, 94 insertions(+), 47 deletions(-) diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index 492c178..d24432b 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -9,7 +9,10 @@ // namespace sim{ +static int id_incr = 1; + TcpLink::TcpLink(bool is_server){ + _id = id_incr++; sock = -1; noblock_ = false; remote_ip[0] = '\0'; @@ -22,6 +25,10 @@ TcpLink::~TcpLink(){ delete _buffer; } +int TcpLink::id() const{ + return _id; +} + int TcpLink::fd() const{ return sock; } diff --git a/src/net/test.cpp b/src/net/test.cpp index 758325d..e7ab25d 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -3,7 +3,7 @@ // using namespace sim; -#define TICK_INTERVAL 100 // ms +#define TICK_INTERVAL 1000 // ms volatile bool quit = false; void signal_handler(int sig){ @@ -23,31 +23,32 @@ int main(int argc, char **argv){ signal(SIGPIPE, SIG_IGN); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); -#ifndef __CYGWIN__ - signal(SIGALRM, signal_handler); - { - struct itimerval tv; - tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); - tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; - tv.it_value.tv_sec = 1; - tv.it_value.tv_usec = 0; - setitimer(ITIMER_REAL, &tv, NULL); - } -#endif +// #ifndef __CYGWIN__ +// signal(SIGALRM, signal_handler); +// { +// struct itimerval tv; +// tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); +// tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; +// tv.it_value.tv_sec = 1; +// tv.it_value.tv_usec = 0; +// setitimer(ITIMER_REAL, &tv, NULL); +// } +// #endif Transport *trans = new Transport(); trans->setup(); log_debug("transport setup"); - TcpLink *link = trans->wait(); - if(link->is_new()){ - trans->read(link); - }else if(link->is_closing()){ - trans->close(link); - } while(!quit){ - usleep(100 * 1000); + LinkEvent event = trans->wait(50); + if(event.is_new()){ + log_debug("accept"); + trans->accept(event.id()); + }else if(event.is_close()){ + log_debug("close"); + trans->close(event.id()); + } } return 0; } diff --git a/src/net/transport.cpp b/src/net/transport.cpp index c19fce4..6df4e1d 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -7,18 +7,11 @@ Transport::Transport(){ Transport::~Transport(){ } -// TcpLink* Transport::wait(){ -// // while(1){ -// // _signal.wait(); -// // Locking l(&_mutex); -// // -// // if(!_waiting_links.empty()){ -// // TcpLink *link = _waiting_links.front(); -// // _waiting_links.pop_front(); -// // return link; -// // } -// // } -// } +LinkEvent Transport::wait(int timeout_ms){ + LinkEvent event; + _events.pop(&event, timeout_ms); + return event; +} void Transport::accept(int id){ this->_accept_ids.push(id); @@ -54,6 +47,8 @@ void Transport::handle_close_link(TcpLink *link){ _closing_links[id] = link; this->_events.push(LinkEvent::close_link(link)); + + _fdes->del(link->fd()); } void Transport::handle_accept_id(){ diff --git a/src/net/transport.h b/src/net/transport.h index be09c15..453245b 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -13,7 +13,7 @@ class LinkEvent { public: LinkEvent(){ - _status = 0; + _status = -1; } LinkEvent(int id, int status){ _id = id; @@ -23,6 +23,9 @@ class LinkEvent int id() const{ return _id; } + bool is_none() const{ + return _status == -1; + } bool is_new() const{ return _status == 0; } @@ -32,7 +35,6 @@ class LinkEvent bool is_read() const{ return _status == 2; } - static LinkEvent new_link(TcpLink *link){ return LinkEvent(link->id(), 0); } @@ -55,7 +57,7 @@ class Transport Transport(); ~Transport(); - LinkEvent wait(); + LinkEvent wait(int timeout_ms); void accept(int id); void close(int id); diff --git a/src/util/thread.h b/src/util/thread.h index 5e6a0a1..ac88f9e 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -14,6 +14,8 @@ found in the LICENSE file. #include #include #include +#include +#include class Mutex{ private: @@ -84,19 +86,19 @@ class Locking{ // Thread safe queue template class Queue{ - private: - pthread_cond_t cond; - pthread_mutex_t mutex; - std::queue items; - public: - Queue(); - ~Queue(); +private: + pthread_cond_t cond; + pthread_mutex_t mutex; + std::queue items; +public: + Queue(); + ~Queue(); - bool empty(); - int size(); - int push(const T item); - // TODO: with timeout - int pop(T *data); + bool empty(); + int size(); + int push(const T item); + int pop(T *data); + int pop(T *data, int timeout_ms); }; template @@ -152,7 +154,7 @@ int Queue::pop(T *data){ return -1; } { - // 必须放在循环中, 因为 pthread_cond_wait 可能抢不到锁而被其它处理了 + // 必须放在循环中, 因为 pthread_cond_wait 可能被中断 while(items.empty()){ //fprintf(stderr, "%d wait\n", pthread_self()); if(pthread_cond_wait(&cond, &mutex) != 0){ @@ -173,6 +175,46 @@ int Queue::pop(T *data){ return 1; } +template +int Queue::pop(T *data, int timeout_ms){ + int ret = 0; + + if(pthread_mutex_lock(&mutex) != 0){ + return -1; + } + { + while(1){ + struct timeval now; + gettimeofday(&now, NULL); + + struct timespec tv; + tv.tv_sec = now.tv_sec + (timeout_ms / 1000); + tv.tv_nsec = (now.tv_usec + timeout_ms * 1000) * 1000; + tv.tv_sec += tv.tv_nsec / (1000 * 1000 * 1000); + tv.tv_nsec %= (1000 * 1000 * 1000); + + int r = pthread_cond_timedwait(&cond, &mutex, &tv); + if(r == ETIMEDOUT){ + ret = 0; + break; + }else if(r == 0){ + ret = 1; + if(!items.empty()){ + *data = items.front(); + items.pop(); + break; + } + } + } + } + if(pthread_mutex_unlock(&mutex) != 0){ + //fprintf(stderr, "error!\n"); + return -1; + } + //fprintf(stderr, "%d wait end 2, job: %d\n", pthread_self(), (int)*data); + return ret; +} + // Selectable queue, multi writers, single reader template class Channel{ From eddb54eb14daf780f2872452ba6ad95d7be2ebc3 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 11:05:47 +0800 Subject: [PATCH 13/31] update --- src/util/thread.h | 65 +++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 45 deletions(-) diff --git a/src/util/thread.h b/src/util/thread.h index ac88f9e..5ca1b00 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -98,7 +98,7 @@ class Queue{ int size(); int push(const T item); int pop(T *data); - int pop(T *data, int timeout_ms); + int pop(T *data, int timeout_ms=-1); }; template @@ -148,33 +148,6 @@ int Queue::push(const T item){ return 1; } -template -int Queue::pop(T *data){ - if(pthread_mutex_lock(&mutex) != 0){ - return -1; - } - { - // 必须放在循环中, 因为 pthread_cond_wait 可能被中断 - while(items.empty()){ - //fprintf(stderr, "%d wait\n", pthread_self()); - if(pthread_cond_wait(&cond, &mutex) != 0){ - //fprintf(stderr, "%s %d -1!\n", __FILE__, __LINE__); - return -1; - } - //fprintf(stderr, "%d wait 2\n", pthread_self()); - } - *data = items.front(); - //fprintf(stderr, "%d job: %d\n", pthread_self(), (int)*data); - items.pop(); - } - if(pthread_mutex_unlock(&mutex) != 0){ - //fprintf(stderr, "error!\n"); - return -1; - } - //fprintf(stderr, "%d wait end 2, job: %d\n", pthread_self(), (int)*data); - return 1; -} - template int Queue::pop(T *data, int timeout_ms){ int ret = 0; @@ -187,31 +160,33 @@ int Queue::pop(T *data, int timeout_ms){ struct timeval now; gettimeofday(&now, NULL); - struct timespec tv; - tv.tv_sec = now.tv_sec + (timeout_ms / 1000); - tv.tv_nsec = (now.tv_usec + timeout_ms * 1000) * 1000; - tv.tv_sec += tv.tv_nsec / (1000 * 1000 * 1000); - tv.tv_nsec %= (1000 * 1000 * 1000); - - int r = pthread_cond_timedwait(&cond, &mutex, &tv); - if(r == ETIMEDOUT){ - ret = 0; - break; - }else if(r == 0){ - ret = 1; - if(!items.empty()){ - *data = items.front(); - items.pop(); + int r; + if(timeout_ms == -1){ + r = pthread_cond_wait(&cond, &mutex); + }else{ + struct timespec tv; + tv.tv_sec = now.tv_sec + (timeout_ms / 1000); + tv.tv_nsec = (now.tv_usec + timeout_ms * 1000) * 1000; + tv.tv_sec += tv.tv_nsec / (1000 * 1000 * 1000); + tv.tv_nsec %= (1000 * 1000 * 1000); + r = pthread_cond_timedwait(&cond, &mutex, &tv); + if(r == ETIMEDOUT){ + ret = 0; break; } } + + if(r == 0 && !items.empty()){ + *data = items.front(); + items.pop(); + ret = 1; + break; + } } } if(pthread_mutex_unlock(&mutex) != 0){ - //fprintf(stderr, "error!\n"); return -1; } - //fprintf(stderr, "%d wait end 2, job: %d\n", pthread_self(), (int)*data); return ret; } From 38356f847f5bb9a4241ccb65e7d3bb906f255cc4 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 12:54:34 +0800 Subject: [PATCH 14/31] update --- src/net/Makefile | 4 +-- src/net/link.cpp | 42 ++++++++++++++++------------- src/net/link.h | 28 ++++++++++--------- src/net/tcp_link.cpp | 48 ++++++--------------------------- src/net/tcp_link.h | 20 +++----------- src/net/transport.cpp | 63 +++++++++++++++++++++++-------------------- src/net/transport.h | 15 ++++++----- 7 files changed, 92 insertions(+), 128 deletions(-) diff --git a/src/net/Makefile b/src/net/Makefile index e45c107..e4413a9 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,12 +1,10 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o tcp_link.o transport.o +OBJS = fde.o link.o tcp_link.o transport.o all: $(OBJS) -fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp - ${CXX} ${CFLAGS} -c fde.cpp .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ diff --git a/src/net/link.cpp b/src/net/link.cpp index 5d7dbdb..c71e673 100644 --- a/src/net/link.cpp +++ b/src/net/link.cpp @@ -1,39 +1,43 @@ #include "link.h" #include +#include + +static int id_incr = 1; Link::Link(){ - _status = 0; + _id = id_incr++; _fd = -1; + _nonblock = false; } Link::~Link(){ + this->close(); } -int Link::fd() const{ - return _fd; -} - -bool Link::is_new() const{ - return _status == 0; +int Link::id() const{ + return _id; } -bool Link::is_closed() const{ - return _status == 1; +int Link::fd() const{ + return _fd; } -bool Link::is_working() const{ - return _status == 2; +void Link::close(){ + if(_fd >= 0){ + ::close(_fd); + _fd = -1; + } } -void Link::accept(){ - _status = 2; +bool Link::nonblock() const{ + return _nonblock; } -void Link::close(){ - if(is_closed()){ - return; +void Link::nonblock(bool enable){ + _nonblock = enable; + if(enable){ + ::fcntl(_fd, F_SETFL, O_NONBLOCK | O_RDWR); + }else{ + ::fcntl(_fd, F_SETFL, O_RDWR); } - _status = 1; - ::close(_fd); - _fd = -1; } diff --git a/src/net/link.h b/src/net/link.h index c807962..4ef92db 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -1,29 +1,31 @@ #ifndef SIM_LINK_H #define SIM_LINK_H +#include + class Link { public: + // TODO: + char remote_ip[INET_ADDRSTRLEN]; + int remote_port; + Link(); + virtual ~Link(); + int id() const; int fd() const; + void close(); - bool is_new() const; - bool is_closed() const; - bool is_working() const; - - friend class Transport; - -protected: - int _status; - -private: - virtual ~Link(); + bool nonblock() const; + void nonblock(bool enable); +protected: + int _id; int _fd; - void accept(); - void close(); +private: + bool _nonblock; }; #endif diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index d24432b..fd9d72e 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -9,59 +8,28 @@ // namespace sim{ -static int id_incr = 1; - TcpLink::TcpLink(bool is_server){ - _id = id_incr++; - sock = -1; - noblock_ = false; remote_ip[0] = '\0'; remote_port = -1; _buffer = new Buffer(); } TcpLink::~TcpLink(){ - this->close(); delete _buffer; } -int TcpLink::id() const{ - return _id; -} - -int TcpLink::fd() const{ - return sock; -} - Buffer* TcpLink::buffer() const{ return _buffer; } -void TcpLink::close(){ - if(sock >= 0){ - ::close(sock); - sock = -1; - } - _status = -1; -} - void TcpLink::nodelay(bool enable){ int opt = enable? 1 : 0; - ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); + ::setsockopt(fd(), IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); } void TcpLink::keepalive(bool enable){ int opt = enable? 1 : 0; - ::setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); -} - -void TcpLink::noblock(bool enable){ - noblock_ = enable; - if(enable){ - ::fcntl(sock, F_SETFL, O_NONBLOCK | O_RDWR); - }else{ - ::fcntl(sock, F_SETFL, O_RDWR); - } + ::setsockopt(fd(), SOL_SOCKET, SO_KEEPALIVE, (void *)&opt, sizeof(opt)); } TcpLink* TcpLink::connect(const std::string &ip, int port){ @@ -87,7 +55,7 @@ TcpLink* TcpLink::connect(const char *ip, int port){ //log_debug("fd: %d, connect to %s:%d", sock, ip, port); link = new TcpLink(); - link->sock = sock; + link->_fd = sock; link->keepalive(true); return link; sock_err: @@ -128,7 +96,7 @@ TcpLink* TcpLink::listen(const char *ip, int port){ //log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port); link = new TcpLink(true); - link->sock = sock; + link->_fd = sock; snprintf(link->remote_ip, sizeof(link->remote_ip), "%s", ip); link->remote_port = port; return link; @@ -146,7 +114,7 @@ TcpLink* TcpLink::accept(){ struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); - while((client_sock = ::accept(sock, (struct sockaddr *)&addr, &addrlen)) == -1){ + while((client_sock = ::accept(fd(), (struct sockaddr *)&addr, &addrlen)) == -1){ if(errno != EINTR){ //log_error("socket %d accept failed: %s", sock, strerror(errno)); return NULL; @@ -160,7 +128,7 @@ TcpLink* TcpLink::accept(){ } link = new TcpLink(); - link->sock = client_sock; + link->_fd = client_sock; link->keepalive(true); inet_ntop(AF_INET, &addr.sin_addr, link->remote_ip, sizeof(link->remote_ip)); link->remote_port = ntohs(addr.sin_port); @@ -174,7 +142,7 @@ int TcpLink::net_read(){ while(1){ // test //want = 1; - int len = ::read(sock, buf, want); + int len = ::read(fd(), buf, want); if(len == -1){ if(errno == EINTR){ continue; @@ -193,7 +161,7 @@ int TcpLink::net_read(){ _buffer->append(buf, len); } - if(!noblock_){ + if(!nonblock()){ break; } } diff --git a/src/net/tcp_link.h b/src/net/tcp_link.h index 8498cf9..a41fad4 100644 --- a/src/net/tcp_link.h +++ b/src/net/tcp_link.h @@ -4,29 +4,19 @@ #include #include #include -#include #include #include #include "util/buffer.h" +#include "link.h" // namespace sim{ -class TcpLink{ +class TcpLink : public Link{ public: - char remote_ip[INET_ADDRSTRLEN]; - int remote_port; - - double create_time; - double active_time; - - ~TcpLink(); - void close(); + virtual ~TcpLink(); void nodelay(bool enable=true); - void noblock(bool enable=true); void keepalive(bool enable=true); - int id() const; - int fd() const; Buffer* buffer() const; int net_read(); @@ -39,10 +29,6 @@ class TcpLink{ TcpLink* accept(); private: - int _id; - int sock; - bool noblock_; - int _status; Buffer* _buffer; TcpLink(bool is_server=false); diff --git a/src/net/transport.cpp b/src/net/transport.cpp index 6df4e1d..8a41510 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -18,37 +18,35 @@ void Transport::accept(int id){ } void Transport::close(int id){ - this->_close_ids.push(id); - Locking l(&_mutex); - if(_working_links.find(id) != _working_links.end()){ - TcpLink *link = _working_links[id]; - _working_links.erase(id); - _closing_links[id] = link; + if(_opening_list.find(id) != _opening_list.end()){ + Link *link = _opening_list[id]; + _opening_list.erase(link->id()); + _closing_list[link->id()] = link; + + this->_close_ids.push(id); + } + if(_working_list.find(id) != _working_list.end()){ + Link *link = _working_list[id]; + _working_list.erase(link->id()); + _closing_list[link->id()] = link; + + this->_close_ids.push(id); } } -void Transport::handle_new_link(TcpLink *link){ - log_debug("new link from %s:%d, fd: %d", link->remote_ip, link->remote_port, link->fd()); - +void Transport::handle_on_new(Link *link){ Locking l(&_mutex); - int id = link->id(); - _working_links[id] = link; + _opening_list[link->id()] = link; this->_events.push(LinkEvent::new_link(link)); } -void Transport::handle_close_link(TcpLink *link){ - log_debug("closing link %s:%d", link->remote_ip, link->remote_port); - - Locking l(&_mutex); - int id = link->id(); - _working_links.erase(id); - _closing_links[id] = link; - - this->_events.push(LinkEvent::close_link(link)); - +void Transport::handle_on_close(Link *link){ + this->close(link->id()); + _fdes->del(link->fd()); + this->_events.push(LinkEvent::close_link(link)); } void Transport::handle_accept_id(){ @@ -56,8 +54,12 @@ void Transport::handle_accept_id(){ _accept_ids.pop(&id); Locking l(&_mutex); - if(_working_links.find(id) != _working_links.end()){ - TcpLink *link = _working_links[id]; + if(_opening_list.find(id) != _opening_list.end()){ + Link *link = _opening_list[id]; + log_debug("accept %s:%d", link->remote_ip, link->remote_port); + _opening_list.erase(link->id()); + _working_list[link->id()] = link; + _fdes->set(link->fd(), FDEVENT_IN, 1, link); } } @@ -67,9 +69,10 @@ void Transport::handle_close_id(){ _close_ids.pop(&id); Locking l(&_mutex); - if(_closing_links.find(id) != _closing_links.end()){ - TcpLink *link = _closing_links[id]; - _closing_links.erase(id); + if(_closing_list.find(id) != _closing_list.end()){ + Link *link = _closing_list[id]; + log_debug("close %s:%d", link->remote_ip, link->remote_port); + _closing_list.erase(id); _fdes->del(link->fd()); delete link; @@ -112,17 +115,19 @@ void* Transport::run(void *arg){ }else if(fde->data.ptr == tcp_serv){ TcpLink *link = tcp_serv->accept(); if(link){ - trans->handle_new_link(link); + log_debug("on new %s:%d", link->remote_ip, link->remote_port); + trans->handle_on_new(link); }else{ log_error("accept return NULL"); } }else{ TcpLink *link = (TcpLink *)fde->data.ptr; if(link){ // 防止已经被 fde_del - log_debug("read %s:%d, fd: %d", link->remote_ip, link->remote_port, link->fd()); + log_debug("on read %s:%d", link->remote_ip, link->remote_port); int ret = link->net_read(); if(ret <= 0){ - trans->handle_close_link(link); + log_debug("on close %s:%d", link->remote_ip, link->remote_port); + trans->handle_on_close(link); }else{ // } diff --git a/src/net/transport.h b/src/net/transport.h index 453245b..8b04181 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -35,13 +35,13 @@ class LinkEvent bool is_read() const{ return _status == 2; } - static LinkEvent new_link(TcpLink *link){ + static LinkEvent new_link(Link *link){ return LinkEvent(link->id(), 0); } - static LinkEvent close_link(TcpLink *link){ + static LinkEvent close_link(Link *link){ return LinkEvent(link->id(), 1); } - static LinkEvent read_link(TcpLink *link){ + static LinkEvent read_link(Link *link){ return LinkEvent(link->id(), 2); } @@ -70,16 +70,17 @@ class Transport private: Mutex _mutex; - std::map _working_links; - std::map _closing_links; + std::map _working_list; + std::map _opening_list; + std::map _closing_list; Queue _events; Channel _accept_ids; Channel _close_ids; - void handle_new_link(TcpLink *link); - void handle_close_link(TcpLink *link); + void handle_on_new(Link *link); + void handle_on_close(Link *link); void handle_accept_id(); void handle_close_id(); From b01d2264a7ae2b018bebd7b70c7de376059566e7 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 13:06:27 +0800 Subject: [PATCH 15/31] update --- src/net/link.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/link.h b/src/net/link.h index 4ef92db..8bbb83e 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -21,10 +21,10 @@ class Link void nonblock(bool enable); protected: - int _id; int _fd; private: + int _id; bool _nonblock; }; From f045311174a6d8ee7f8a3e120dfabe5aa16d47a0 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 16:11:32 +0800 Subject: [PATCH 16/31] update --- src/net/Makefile | 2 +- src/net/event.cpp | 40 +++++++++++++++ src/net/event.h | 26 ++++++++++ src/{line => net}/line_message.cpp | 0 src/{line => net}/line_message.h | 0 src/{line => net}/line_parser.cpp | 0 src/{line => net}/line_parser.h | 0 src/net/link.cpp | 11 ++--- src/net/link.h | 13 +++-- src/{ => net}/message.h | 2 +- src/{ => net}/parser.cpp | 0 src/{ => net}/parser.h | 2 +- src/net/session.cpp | 19 ++++++++ src/net/session.h | 20 ++++++++ src/net/tcp_link.cpp | 16 +++--- src/net/tcp_link.h | 3 +- src/net/test.cpp | 6 +-- src/net/transport.cpp | 78 +++++++++++++++++------------- src/net/transport.h | 60 ++++------------------- 19 files changed, 187 insertions(+), 111 deletions(-) create mode 100644 src/net/event.cpp create mode 100644 src/net/event.h rename src/{line => net}/line_message.cpp (100%) rename src/{line => net}/line_message.h (100%) rename src/{line => net}/line_parser.cpp (100%) rename src/{line => net}/line_parser.h (100%) rename src/{ => net}/message.h (81%) rename src/{ => net}/parser.cpp (100%) rename src/{ => net}/parser.h (94%) create mode 100644 src/net/session.cpp create mode 100644 src/net/session.h diff --git a/src/net/Makefile b/src/net/Makefile index e4413a9..4c5d8d4 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,7 +1,7 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o link.o tcp_link.o transport.o +OBJS = fde.o link.o tcp_link.o event.o session.o transport.o all: $(OBJS) diff --git a/src/net/event.cpp b/src/net/event.cpp new file mode 100644 index 0000000..e1da2de --- /dev/null +++ b/src/net/event.cpp @@ -0,0 +1,40 @@ +#include "event.h" + +Event Event::new_event(Session *sess){ + return Event(sess->id(), 0); +} +Event Event::close_event(Session *sess){ + return Event(sess->id(), 1); +} +Event Event::read_event(Session *sess){ + return Event(sess->id(), 2); +} + +Event::Event(){ + _type = -1; +} + +Event::Event(int id, int type){ + _id = id; + _type = type; +} + +int Event::id() const{ + return _id; +} + +bool Event::is_none() const{ + return _type == -1; +} + +bool Event::is_new() const{ + return _type == 0; +} + +bool Event::is_close() const{ + return _type == 1; +} + +bool Event::is_read() const{ + return _type == 2; +} diff --git a/src/net/event.h b/src/net/event.h new file mode 100644 index 0000000..ac238e5 --- /dev/null +++ b/src/net/event.h @@ -0,0 +1,26 @@ +#ifndef SIM_EVENT_H +#define SIM_EVENT_H + +#include "session.h" + +class Event +{ +public: + static Event new_event(Session *sess); + static Event close_event(Session *sess); + static Event read_event(Session *sess); + + Event(); + Event(int id, int type); + int id() const; + bool is_none() const; + bool is_new() const; + bool is_close() const; + bool is_read() const; + +private: + int _id; + int _type; +}; + +#endif diff --git a/src/line/line_message.cpp b/src/net/line_message.cpp similarity index 100% rename from src/line/line_message.cpp rename to src/net/line_message.cpp diff --git a/src/line/line_message.h b/src/net/line_message.h similarity index 100% rename from src/line/line_message.h rename to src/net/line_message.h diff --git a/src/line/line_parser.cpp b/src/net/line_parser.cpp similarity index 100% rename from src/line/line_parser.cpp rename to src/net/line_parser.cpp diff --git a/src/line/line_parser.h b/src/net/line_parser.h similarity index 100% rename from src/line/line_parser.h rename to src/net/line_parser.h diff --git a/src/net/link.cpp b/src/net/link.cpp index c71e673..a77010c 100644 --- a/src/net/link.cpp +++ b/src/net/link.cpp @@ -2,10 +2,7 @@ #include #include -static int id_incr = 1; - Link::Link(){ - _id = id_incr++; _fd = -1; _nonblock = false; } @@ -14,14 +11,14 @@ Link::~Link(){ this->close(); } -int Link::id() const{ - return _id; -} - int Link::fd() const{ return _fd; } +std::string Link::address() const{ + return _address; +} + void Link::close(){ if(_fd >= 0){ ::close(_fd); diff --git a/src/net/link.h b/src/net/link.h index 8bbb83e..be503df 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -2,29 +2,28 @@ #define SIM_LINK_H #include +#include class Link { public: - // TODO: - char remote_ip[INET_ADDRSTRLEN]; - int remote_port; - Link(); virtual ~Link(); - int id() const; int fd() const; - void close(); + std::string address() const; bool nonblock() const; void nonblock(bool enable); + void close(); + virtual int net_read() = 0; + protected: int _fd; + std::string _address; private: - int _id; bool _nonblock; }; diff --git a/src/message.h b/src/net/message.h similarity index 81% rename from src/message.h rename to src/net/message.h index 8fae43c..4fa7d38 100644 --- a/src/message.h +++ b/src/net/message.h @@ -1,7 +1,7 @@ #ifndef SIM_MESSAGE_H #define SIM_MESSAGE_H -#include "buffer.h" +#include "util/buffer.h" class Message { diff --git a/src/parser.cpp b/src/net/parser.cpp similarity index 100% rename from src/parser.cpp rename to src/net/parser.cpp diff --git a/src/parser.h b/src/net/parser.h similarity index 94% rename from src/parser.h rename to src/net/parser.h index c2fa7e2..2df81a3 100644 --- a/src/parser.h +++ b/src/net/parser.h @@ -1,7 +1,7 @@ #ifndef SIM_PARSER_H #define SIM_PARSER_H -#include "buffer.h" +#include "util/buffer.h" #include "message.h" class ParseStatus; diff --git a/src/net/session.cpp b/src/net/session.cpp new file mode 100644 index 0000000..03f8002 --- /dev/null +++ b/src/net/session.cpp @@ -0,0 +1,19 @@ +#include "session.h" + +static int id_incr = 1; + +Session::Session(Link *link){ + _id = id_incr++; + _link = link; +} + +Session::~Session(){ +} + +int Session::id() const{ + return _id; +} + +Link* Session::link() const{ + return _link; +} diff --git a/src/net/session.h b/src/net/session.h new file mode 100644 index 0000000..b0d2934 --- /dev/null +++ b/src/net/session.h @@ -0,0 +1,20 @@ +#ifndef SIM_SESSION_H +#define SIM_SESSION_H + +#include "link.h" + +class Session +{ +public: + Session(Link *link); + ~Session(); + + int id() const; + Link* link() const; + +private: + int _id; + Link *_link; +}; + +#endif diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index fd9d72e..dce85f7 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -9,8 +9,6 @@ // namespace sim{ TcpLink::TcpLink(bool is_server){ - remote_ip[0] = '\0'; - remote_port = -1; _buffer = new Buffer(); } @@ -94,11 +92,13 @@ TcpLink* TcpLink::listen(const char *ip, int port){ goto sock_err; } //log_debug("server socket fd: %d, listen on: %s:%d", sock, ip, port); + char s[INET_ADDRSTRLEN + 6]; + snprintf(s, sizeof(s), "%s:%d", ip, port); link = new TcpLink(true); link->_fd = sock; - snprintf(link->remote_ip, sizeof(link->remote_ip), "%s", ip); - link->remote_port = port; + link->_address = s; + return link; sock_err: //log_debug("listen %s:%d failed: %s", ip, port, strerror(errno)); @@ -127,11 +127,15 @@ TcpLink* TcpLink::accept(){ //log_error("socket %d set linger failed: %s", client_sock, strerror(errno)); } + char s[INET_ADDRSTRLEN + 6]; + inet_ntop(AF_INET, &addr.sin_addr, s, sizeof(s)); + int len = strlen(s); + snprintf(s+len, sizeof(s) - len, "%d", ntohs(addr.sin_port)); + link = new TcpLink(); link->_fd = client_sock; + link->_address = s; link->keepalive(true); - inet_ntop(AF_INET, &addr.sin_addr, link->remote_ip, sizeof(link->remote_ip)); - link->remote_port = ntohs(addr.sin_port); return link; } diff --git a/src/net/tcp_link.h b/src/net/tcp_link.h index a41fad4..c83f50a 100644 --- a/src/net/tcp_link.h +++ b/src/net/tcp_link.h @@ -14,12 +14,13 @@ class TcpLink : public Link{ public: virtual ~TcpLink(); + void nodelay(bool enable=true); void keepalive(bool enable=true); Buffer* buffer() const; - int net_read(); + virtual int net_read(); // int net_write(); static TcpLink* connect(const char *ip, int port); diff --git a/src/net/test.cpp b/src/net/test.cpp index e7ab25d..085a6f2 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -38,10 +38,9 @@ int main(int argc, char **argv){ Transport *trans = new Transport(); trans->setup(); log_debug("transport setup"); - - + while(!quit){ - LinkEvent event = trans->wait(50); + Event event = trans->wait(50); if(event.is_new()){ log_debug("accept"); trans->accept(event.id()); @@ -50,5 +49,6 @@ int main(int argc, char **argv){ trans->close(event.id()); } } + return 0; } diff --git a/src/net/transport.cpp b/src/net/transport.cpp index 8a41510..549d962 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -1,5 +1,8 @@ #include "transport.h" #include "util/log.h" +#include "line_parser.h" +#include "line_message.h" +#include "tcp_link.h" Transport::Transport(){ } @@ -7,8 +10,8 @@ Transport::Transport(){ Transport::~Transport(){ } -LinkEvent Transport::wait(int timeout_ms){ - LinkEvent event; +Event Transport::wait(int timeout_ms){ + Event event; _events.pop(&event, timeout_ms); return event; } @@ -20,33 +23,36 @@ void Transport::accept(int id){ void Transport::close(int id){ Locking l(&_mutex); if(_opening_list.find(id) != _opening_list.end()){ - Link *link = _opening_list[id]; - _opening_list.erase(link->id()); - _closing_list[link->id()] = link; + Session *sess = _opening_list[id]; + _opening_list.erase(sess->id()); + _closing_list[sess->id()] = sess; this->_close_ids.push(id); } if(_working_list.find(id) != _working_list.end()){ - Link *link = _working_list[id]; - _working_list.erase(link->id()); - _closing_list[link->id()] = link; + Session *sess = _working_list[id]; + _working_list.erase(sess->id()); + _closing_list[sess->id()] = sess; this->_close_ids.push(id); } } -void Transport::handle_on_new(Link *link){ +void Transport::handle_on_new(Session *sess){ + log_debug("on new %s", sess->link()->address().c_str()); + Locking l(&_mutex); - _opening_list[link->id()] = link; + _opening_list[sess->id()] = sess; - this->_events.push(LinkEvent::new_link(link)); + this->_events.push(Event::new_event(sess)); } -void Transport::handle_on_close(Link *link){ - this->close(link->id()); +void Transport::handle_on_close(Session *sess){ + log_debug("on close %s", sess->link()->address().c_str()); + this->close(sess->id()); - _fdes->del(link->fd()); - this->_events.push(LinkEvent::close_link(link)); + _fdes->del(sess->link()->fd()); + this->_events.push(Event::close_event(sess)); } void Transport::handle_accept_id(){ @@ -55,12 +61,12 @@ void Transport::handle_accept_id(){ Locking l(&_mutex); if(_opening_list.find(id) != _opening_list.end()){ - Link *link = _opening_list[id]; - log_debug("accept %s:%d", link->remote_ip, link->remote_port); - _opening_list.erase(link->id()); - _working_list[link->id()] = link; + Session *sess = _opening_list[id]; + log_debug("accept %s", sess->link()->address().c_str()); + _opening_list.erase(sess->id()); + _working_list[sess->id()] = sess; - _fdes->set(link->fd(), FDEVENT_IN, 1, link); + _fdes->set(sess->link()->fd(), FDEVENT_IN, 1, sess); } } @@ -70,12 +76,12 @@ void Transport::handle_close_id(){ Locking l(&_mutex); if(_closing_list.find(id) != _closing_list.end()){ - Link *link = _closing_list[id]; - log_debug("close %s:%d", link->remote_ip, link->remote_port); + Session *sess = _closing_list[id]; + log_debug("close %s", sess->link()->address().c_str()); _closing_list.erase(id); - _fdes->del(link->fd()); - delete link; + _fdes->del(sess->link()->fd()); + delete sess; } } @@ -113,23 +119,29 @@ void* Transport::run(void *arg){ }else if(fde->data.ptr == &trans->_close_ids){ trans->handle_close_id(); }else if(fde->data.ptr == tcp_serv){ - TcpLink *link = tcp_serv->accept(); + Link *link = tcp_serv->accept(); if(link){ - log_debug("on new %s:%d", link->remote_ip, link->remote_port); - trans->handle_on_new(link); + Session *sess = new Session(link); + trans->handle_on_new(sess); }else{ log_error("accept return NULL"); } }else{ - TcpLink *link = (TcpLink *)fde->data.ptr; - if(link){ // 防止已经被 fde_del - log_debug("on read %s:%d", link->remote_ip, link->remote_port); + Session *sess = (Session *)fde->data.ptr; + if(sess){ // 防止已经被 fde_del + log_debug("net read %s", sess->link()->address().c_str()); + Link *link = sess->link(); int ret = link->net_read(); if(ret <= 0){ - log_debug("on close %s:%d", link->remote_ip, link->remote_port); - trans->handle_on_close(link); + trans->handle_on_close(sess); }else{ - // + // LineParser parser; + // Buffer *buffer = link->buffer(); + // Message *msg; + // ParseStatus s = parser.parse(buffer, &msg); + // if(s.ok()){ + // log_debug("recv: %s", ((LineMessage *)msg)->text().c_str()); + // } } } } diff --git a/src/net/transport.h b/src/net/transport.h index 8b04181..ecb748a 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -3,61 +3,19 @@ #include #include "util/thread.h" -#include "tcp_link.h" #include "fde.h" +#include "event.h" +#include "session.h" using namespace sim; - -class LinkEvent -{ -public: - LinkEvent(){ - _status = -1; - } - LinkEvent(int id, int status){ - _id = id; - _status = status; - } - - int id() const{ - return _id; - } - bool is_none() const{ - return _status == -1; - } - bool is_new() const{ - return _status == 0; - } - bool is_close() const{ - return _status == 1; - } - bool is_read() const{ - return _status == 2; - } - static LinkEvent new_link(Link *link){ - return LinkEvent(link->id(), 0); - } - static LinkEvent close_link(Link *link){ - return LinkEvent(link->id(), 1); - } - static LinkEvent read_link(Link *link){ - return LinkEvent(link->id(), 2); - } - - friend class Transport; -private: - int _id; - int _status; -}; - class Transport { public: Transport(); ~Transport(); - LinkEvent wait(int timeout_ms); + Event wait(int timeout_ms); void accept(int id); void close(int id); @@ -70,17 +28,17 @@ class Transport private: Mutex _mutex; - std::map _working_list; - std::map _opening_list; - std::map _closing_list; + std::map _working_list; + std::map _opening_list; + std::map _closing_list; - Queue _events; + Queue _events; Channel _accept_ids; Channel _close_ids; - void handle_on_new(Link *link); - void handle_on_close(Link *link); + void handle_on_new(Session *sess); + void handle_on_close(Session *sess); void handle_accept_id(); void handle_close_id(); From d5bb120d11506d41013f5b69b98a891861f0cb46 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 16:56:27 +0800 Subject: [PATCH 17/31] update --- src/net/Makefile | 3 ++- src/net/line_parser.cpp | 12 ++++++------ src/net/line_parser.h | 4 +--- src/net/link.cpp | 7 +++++++ src/net/link.h | 4 ++++ src/net/parser.cpp | 35 +++++++++++++++++++---------------- src/net/parser.h | 25 ++++++++++++++----------- src/net/session.cpp | 33 ++++++++++++++++++++++++++++++++- src/net/session.h | 16 ++++++++++++++-- src/net/tcp_link.cpp | 9 ++------- src/net/tcp_link.h | 4 ---- src/net/transport.cpp | 16 ++++++++-------- 12 files changed, 109 insertions(+), 59 deletions(-) diff --git a/src/net/Makefile b/src/net/Makefile index 4c5d8d4..cdfeacf 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,7 +1,8 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o link.o tcp_link.o event.o session.o transport.o +OBJS = fde.o link.o tcp_link.o event.o session.o transport.o \ + parser.o line_parser.o line_message.o all: $(OBJS) diff --git a/src/net/line_parser.cpp b/src/net/line_parser.cpp index 7c506c9..853297e 100644 --- a/src/net/line_parser.cpp +++ b/src/net/line_parser.cpp @@ -1,12 +1,13 @@ #include "line_parser.h" +#include +#include "util/buffer.h" +#include "line_message.h" -ParseStatus LineParser::parse(Buffer *buffer, Message **msg){ - ParseStatus ret; - +ParseState LineParser::parse(Buffer *buffer, Message **msg){ const char *data = buffer->data(); char *end = (char *)memchr(data, '\n', buffer->size()); if(!end){ - return ret; + return ParseState::none_state(); } int len = end - data; // 兼容 \r\n @@ -19,6 +20,5 @@ ParseStatus LineParser::parse(Buffer *buffer, Message **msg){ lm->text(s); *msg = lm; - ret.set_ok(); - return ret; + return ParseState::ready_state(); } diff --git a/src/net/line_parser.h b/src/net/line_parser.h index f101949..ce769ce 100644 --- a/src/net/line_parser.h +++ b/src/net/line_parser.h @@ -1,14 +1,12 @@ #ifndef SIM_LINE_PARSER_H #define SIM_LINE_PARSER_H -#include #include "parser.h" -#include "line_message.h" class LineParser : public Parser { public: - virtual ParseStatus parse(Buffer *buffer, Message **msg); + virtual ParseState parse(Buffer *buffer, Message **msg); }; #endif diff --git a/src/net/link.cpp b/src/net/link.cpp index a77010c..5749edf 100644 --- a/src/net/link.cpp +++ b/src/net/link.cpp @@ -1,20 +1,27 @@ #include "link.h" #include #include +#include "util/buffer.h" Link::Link(){ _fd = -1; _nonblock = false; + _buffer = new Buffer(); } Link::~Link(){ this->close(); + delete _buffer; } int Link::fd() const{ return _fd; } +Buffer* Link::buffer() const{ + return _buffer; +} + std::string Link::address() const{ return _address; } diff --git a/src/net/link.h b/src/net/link.h index be503df..25e72a6 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -4,6 +4,8 @@ #include #include +class Buffer; + class Link { public: @@ -11,6 +13,7 @@ class Link virtual ~Link(); int fd() const; + Buffer* buffer() const; std::string address() const; bool nonblock() const; @@ -21,6 +24,7 @@ class Link protected: int _fd; + Buffer* _buffer; std::string _address; private: diff --git a/src/net/parser.cpp b/src/net/parser.cpp index 646a329..a1302e4 100644 --- a/src/net/parser.cpp +++ b/src/net/parser.cpp @@ -1,34 +1,37 @@ #include "parser.h" -ParseStatus::ParseStatus(){ - _code = 0; +ParseState ParseState::none_state(){ + return ParseState(0); } -ParseStatus::~ParseStatus(){ +ParseState ParseState::ready_state(){ + return ParseState(1); } -bool ParseStatus::ok() const{ - return _code == 1; +ParseState ParseState::error_state(){ + return ParseState(-1); } -bool ParseStatus::none() const{ - return _code == 0; -} +// ParseState::ParseState(){ +// _code = 0; +// } -bool ParseStatus::error() const{ - return _code == -1; +ParseState::ParseState(int code){ + _code = code; } +ParseState::~ParseState(){ +} -void ParseStatus::set_ok(){ - _code = 1; +bool ParseState::none() const{ + return _code == 0; } -void ParseStatus::set_none(){ - _code = 0; +bool ParseState::ready() const{ + return _code == 1; } -void ParseStatus::set_error(){ - _code = -1; +bool ParseState::error() const{ + return _code == -1; } diff --git a/src/net/parser.h b/src/net/parser.h index 2df81a3..b6b1ed2 100644 --- a/src/net/parser.h +++ b/src/net/parser.h @@ -1,34 +1,37 @@ #ifndef SIM_PARSER_H #define SIM_PARSER_H -#include "util/buffer.h" #include "message.h" -class ParseStatus; +class Buffer; +class ParseState; class Parser { public: - virtual ParseStatus parse(Buffer *buffer, Message **msg) = 0; + virtual ~Parser(){}; + virtual ParseState parse(Buffer *buffer, Message **msg) = 0; }; ///////////////////////////////////////// -class ParseStatus +class ParseState { public: - ParseStatus(); - ~ParseStatus(); + static ParseState none_state(); + static ParseState ready_state(); + static ParseState error_state(); + + // ParseState(); + ~ParseState(); - bool ok() const; bool none() const; + bool ready() const; bool error() const; - void set_ok(); - void set_none(); - void set_error(); - private: + ParseState(int code); + int _code; }; diff --git a/src/net/session.cpp b/src/net/session.cpp index 03f8002..d43f1da 100644 --- a/src/net/session.cpp +++ b/src/net/session.cpp @@ -1,13 +1,17 @@ #include "session.h" +#include "util/log.h" static int id_incr = 1; -Session::Session(Link *link){ +Session::Session(Link *link, Parser *parser){ _id = id_incr++; _link = link; + _parser = parser; } Session::~Session(){ + delete _link; + delete _parser; } int Session::id() const{ @@ -17,3 +21,30 @@ int Session::id() const{ Link* Session::link() const{ return _link; } + +Parser* Session::parser() const{ + return _parser; +} + +ParseState Session::parse(){ + while(1){ + Message *msg; + ParseState s = _parser->parse(_link->buffer(), &msg); + if(s.ready()){ + _input.push_back(msg); + }else if(s.error()){ + _input.clear(); + _output.clear(); + return s; + }else{ + break; + } + } + + log_debug("received %d message(s)", (int)_input.size()); + if(_input.empty()){ + return ParseState::none_state(); + }else{ + return ParseState::ready_state(); + } +} diff --git a/src/net/session.h b/src/net/session.h index b0d2934..3e98abf 100644 --- a/src/net/session.h +++ b/src/net/session.h @@ -1,20 +1,32 @@ #ifndef SIM_SESSION_H #define SIM_SESSION_H +#include #include "link.h" +#include "parser.h" +#include "message.h" class Session { public: - Session(Link *link); + Session(Link *link, Parser *parser); ~Session(); int id() const; Link* link() const; - + Parser* parser() const; + + ParseState parse(); + + Message* recv(); + private: int _id; Link *_link; + Parser *_parser; + + std::list _input; + std::list _output; }; #endif diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index dce85f7..956dfc7 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -3,21 +3,16 @@ #include #include #include -#include "util/log.h" #include "tcp_link.h" +#include "util/log.h" +#include "util/buffer.h" // namespace sim{ TcpLink::TcpLink(bool is_server){ - _buffer = new Buffer(); } TcpLink::~TcpLink(){ - delete _buffer; -} - -Buffer* TcpLink::buffer() const{ - return _buffer; } void TcpLink::nodelay(bool enable){ diff --git a/src/net/tcp_link.h b/src/net/tcp_link.h index c83f50a..3c020a1 100644 --- a/src/net/tcp_link.h +++ b/src/net/tcp_link.h @@ -6,7 +6,6 @@ #include #include #include -#include "util/buffer.h" #include "link.h" // namespace sim{ @@ -18,8 +17,6 @@ class TcpLink : public Link{ void nodelay(bool enable=true); void keepalive(bool enable=true); - Buffer* buffer() const; - virtual int net_read(); // int net_write(); @@ -30,7 +27,6 @@ class TcpLink : public Link{ TcpLink* accept(); private: - Buffer* _buffer; TcpLink(bool is_server=false); }; diff --git a/src/net/transport.cpp b/src/net/transport.cpp index 549d962..f1d5721 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -121,7 +121,7 @@ void* Transport::run(void *arg){ }else if(fde->data.ptr == tcp_serv){ Link *link = tcp_serv->accept(); if(link){ - Session *sess = new Session(link); + Session *sess = new Session(link, new LineParser()); trans->handle_on_new(sess); }else{ log_error("accept return NULL"); @@ -135,13 +135,13 @@ void* Transport::run(void *arg){ if(ret <= 0){ trans->handle_on_close(sess); }else{ - // LineParser parser; - // Buffer *buffer = link->buffer(); - // Message *msg; - // ParseStatus s = parser.parse(buffer, &msg); - // if(s.ok()){ - // log_debug("recv: %s", ((LineMessage *)msg)->text().c_str()); - // } + ParseState s = sess->parse(); + if(s.ready()){ + trans->_events.push(Event::read_event(sess)); + }else if(s.error()){ + log_debug("parse error!"); + trans->handle_on_close(sess); + } } } } From 403d95f5f44df055c8fa58e14301d87a3bf225c8 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 18:33:11 +0800 Subject: [PATCH 18/31] update --- src/net/event.h | 2 +- src/net/line_parser.cpp | 3 ++ src/net/message.h | 1 + src/net/parser.cpp | 6 ++-- src/net/parser.h | 2 +- src/net/session.cpp | 30 +++++++++++++------ src/net/session.h | 5 ++-- src/net/test.cpp | 16 ++++++++-- src/net/transport.cpp | 66 ++++++++++++++++++++++++++++------------- src/net/transport.h | 3 +- src/util/buffer.cpp | 2 +- src/util/thread.h | 36 +++++++++++----------- 12 files changed, 112 insertions(+), 60 deletions(-) diff --git a/src/net/event.h b/src/net/event.h index ac238e5..e9a4534 100644 --- a/src/net/event.h +++ b/src/net/event.h @@ -16,7 +16,7 @@ class Event bool is_none() const; bool is_new() const; bool is_close() const; - bool is_read() const; + bool is_read() const; // 收到一个报文 private: int _id; diff --git a/src/net/line_parser.cpp b/src/net/line_parser.cpp index 853297e..c9b3f8e 100644 --- a/src/net/line_parser.cpp +++ b/src/net/line_parser.cpp @@ -9,6 +9,7 @@ ParseState LineParser::parse(Buffer *buffer, Message **msg){ if(!end){ return ParseState::none_state(); } + int total = end - data + 1; int len = end - data; // 兼容 \r\n if(len >= 1 && data[len - 1] == '\r'){ @@ -20,5 +21,7 @@ ParseState LineParser::parse(Buffer *buffer, Message **msg){ lm->text(s); *msg = lm; + buffer->remove(total); + return ParseState::ready_state(); } diff --git a/src/net/message.h b/src/net/message.h index 4fa7d38..6eee55d 100644 --- a/src/net/message.h +++ b/src/net/message.h @@ -6,6 +6,7 @@ class Message { public: + virtual ~Message(){} virtual Buffer* encode() = 0; }; diff --git a/src/net/parser.cpp b/src/net/parser.cpp index a1302e4..f9909ec 100644 --- a/src/net/parser.cpp +++ b/src/net/parser.cpp @@ -12,9 +12,9 @@ ParseState ParseState::error_state(){ return ParseState(-1); } -// ParseState::ParseState(){ -// _code = 0; -// } +ParseState::ParseState(){ + _code = 0; +} ParseState::ParseState(int code){ _code = code; diff --git a/src/net/parser.h b/src/net/parser.h index b6b1ed2..40927c2 100644 --- a/src/net/parser.h +++ b/src/net/parser.h @@ -22,7 +22,7 @@ class ParseState static ParseState ready_state(); static ParseState error_state(); - // ParseState(); + ParseState(); ~ParseState(); bool none() const; diff --git a/src/net/session.cpp b/src/net/session.cpp index d43f1da..987cf04 100644 --- a/src/net/session.cpp +++ b/src/net/session.cpp @@ -12,6 +12,14 @@ Session::Session(Link *link, Parser *parser){ Session::~Session(){ delete _link; delete _parser; + for(std::list::iterator it=_input.begin(); it!=_input.end(); it++){ + Message *msg = *it; + delete msg; + } + for(std::list::iterator it=_output.begin(); it!=_output.end(); it++){ + Message *msg = *it; + delete msg; + } } int Session::id() const{ @@ -26,25 +34,29 @@ Parser* Session::parser() const{ return _parser; } -ParseState Session::parse(){ +int Session::parse(){ + int ret = 0; while(1){ Message *msg; ParseState s = _parser->parse(_link->buffer(), &msg); if(s.ready()){ _input.push_back(msg); + ret ++; }else if(s.error()){ - _input.clear(); - _output.clear(); - return s; + return -1; }else{ break; } } - - log_debug("received %d message(s)", (int)_input.size()); + log_debug("received %d message(s)", ret); + return ret; +} + +Message* Session::recv(){ if(_input.empty()){ - return ParseState::none_state(); - }else{ - return ParseState::ready_state(); + return NULL; } + Message *msg = _input.front(); + _input.pop_front(); + return msg; } diff --git a/src/net/session.h b/src/net/session.h index 3e98abf..29efaac 100644 --- a/src/net/session.h +++ b/src/net/session.h @@ -16,8 +16,9 @@ class Session Link* link() const; Parser* parser() const; - ParseState parse(); - + // 返回解析成功的报文数量,出错返回-1 + int parse(); + Message* recv(); private: diff --git a/src/net/test.cpp b/src/net/test.cpp index 085a6f2..ddce7bb 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -1,5 +1,6 @@ #include "transport.h" #include "util/log.h" +#include "line_message.h" // using namespace sim; @@ -29,8 +30,8 @@ int main(int argc, char **argv){ // struct itimerval tv; // tv.it_interval.tv_sec = (TICK_INTERVAL / 1000); // tv.it_interval.tv_usec = (TICK_INTERVAL % 1000) * 1000; -// tv.it_value.tv_sec = 1; -// tv.it_value.tv_usec = 0; +// tv.it_value.tv_sec = 0; +// tv.it_value.tv_usec = TICK_INTERVAL * 1000; // setitimer(ITIMER_REAL, &tv, NULL); // } // #endif @@ -40,13 +41,22 @@ int main(int argc, char **argv){ log_debug("transport setup"); while(!quit){ - Event event = trans->wait(50); + Event event = trans->wait(200); if(event.is_new()){ log_debug("accept"); trans->accept(event.id()); }else if(event.is_close()){ log_debug("close"); trans->close(event.id()); + }else if(event.is_read()){ + // log_debug("read"); + LineMessage *msg = (LineMessage *)trans->recv(event.id()); + if(!msg){ + log_debug("recv NULL msg, detect session closed"); + }else{ + log_debug("recv: %s", msg->text().c_str()); + delete msg; + } } } diff --git a/src/net/transport.cpp b/src/net/transport.cpp index f1d5721..bd1556d 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -26,16 +26,23 @@ void Transport::close(int id){ Session *sess = _opening_list[id]; _opening_list.erase(sess->id()); _closing_list[sess->id()] = sess; - - this->_close_ids.push(id); } if(_working_list.find(id) != _working_list.end()){ Session *sess = _working_list[id]; _working_list.erase(sess->id()); _closing_list[sess->id()] = sess; - - this->_close_ids.push(id); } + + this->_close_ids.push(id); +} + +Message* Transport::recv(int id){ + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + Session *sess = _working_list[id]; + return sess->recv(); + } + return NULL; } void Transport::handle_on_new(Session *sess){ @@ -48,11 +55,41 @@ void Transport::handle_on_new(Session *sess){ } void Transport::handle_on_close(Session *sess){ + int id = sess->id(); log_debug("on close %s", sess->link()->address().c_str()); - this->close(sess->id()); + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + _working_list.erase(sess->id()); + _closing_list[sess->id()] = sess; + + _fdes->del(sess->link()->fd()); + this->_events.push(Event::close_event(sess)); + } +} + +void Transport::handle_on_read(Session *sess){ + // log_debug("net read %s", sess->link()->address().c_str()); - _fdes->del(sess->link()->fd()); - this->_events.push(Event::close_event(sess)); + bool error = false; + int ret = sess->link()->net_read(); + if(ret <= 0){ + error = true; + }else{ + Locking l(&_mutex); + int num = sess->parse(); + if(num == -1){ + log_debug("parse error!"); + error = true; + }else{ + for(int i=0; i_events.push(Event::read_event(sess)); + } + } + } + + if(error){ + this->handle_on_close(sess); + } } void Transport::handle_accept_id(){ @@ -129,20 +166,7 @@ void* Transport::run(void *arg){ }else{ Session *sess = (Session *)fde->data.ptr; if(sess){ // 防止已经被 fde_del - log_debug("net read %s", sess->link()->address().c_str()); - Link *link = sess->link(); - int ret = link->net_read(); - if(ret <= 0){ - trans->handle_on_close(sess); - }else{ - ParseState s = sess->parse(); - if(s.ready()){ - trans->_events.push(Event::read_event(sess)); - }else if(s.error()){ - log_debug("parse error!"); - trans->handle_on_close(sess); - } - } + trans->handle_on_read(sess); } } } diff --git a/src/net/transport.h b/src/net/transport.h index ecb748a..39644cd 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -20,7 +20,7 @@ class Transport void accept(int id); void close(int id); - // Message* recv(int id); + Message* recv(int id); // void send(int id, Message *msg); void setup(); @@ -39,6 +39,7 @@ class Transport void handle_on_new(Session *sess); void handle_on_close(Session *sess); + void handle_on_read(Session *sess); void handle_accept_id(); void handle_close_id(); diff --git a/src/util/buffer.cpp b/src/util/buffer.cpp index 5ad6d2b..a28ca73 100644 --- a/src/util/buffer.cpp +++ b/src/util/buffer.cpp @@ -21,7 +21,7 @@ char* Buffer::data(){ } int Buffer::remove(int count){ - memmove(_buf + count, _buf, _size - count); + memmove(_buf, _buf + count, _size - count); _size -= count; return count; } diff --git a/src/util/thread.h b/src/util/thread.h index 5ca1b00..00d7709 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -156,33 +156,33 @@ int Queue::pop(T *data, int timeout_ms){ return -1; } { - while(1){ - struct timeval now; - gettimeofday(&now, NULL); - - int r; + while(items.empty()){ if(timeout_ms == -1){ - r = pthread_cond_wait(&cond, &mutex); + // 可能被系统中断 + pthread_cond_wait(&cond, &mutex); }else{ + struct timeval now; + gettimeofday(&now, NULL); + struct timespec tv; tv.tv_sec = now.tv_sec + (timeout_ms / 1000); - tv.tv_nsec = (now.tv_usec + timeout_ms * 1000) * 1000; + tv.tv_nsec = (now.tv_usec + (timeout_ms % 1000) * 1000) * 1000; tv.tv_sec += tv.tv_nsec / (1000 * 1000 * 1000); tv.tv_nsec %= (1000 * 1000 * 1000); - r = pthread_cond_timedwait(&cond, &mutex, &tv); - if(r == ETIMEDOUT){ - ret = 0; - break; - } - } - - if(r == 0 && !items.empty()){ - *data = items.front(); - items.pop(); - ret = 1; + // 超时精确度较差,误差在 5ms 级别 + // 可能被系统中断 + pthread_cond_timedwait(&cond, &mutex, &tv); + // pthread_cond_timedwait() == ETIMEDOUT break; } } + if(items.empty()){ + ret = 0; + }else{ + ret = 1; + *data = items.front(); + items.pop(); + } } if(pthread_mutex_unlock(&mutex) != 0){ return -1; From 62e7ee13f198f9fd972fe17939f8fa8db2010d5b Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 18:40:10 +0800 Subject: [PATCH 19/31] update --- src/net/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net/test.cpp b/src/net/test.cpp index ddce7bb..4f8870b 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -52,11 +52,13 @@ int main(int argc, char **argv){ // log_debug("read"); LineMessage *msg = (LineMessage *)trans->recv(event.id()); if(!msg){ + // do nothing, the close event will finally be triggered log_debug("recv NULL msg, detect session closed"); }else{ log_debug("recv: %s", msg->text().c_str()); delete msg; } + usleep(100 * 1000); } } From efb7a70015f9e3623479c0faafeb87c53d55d12f Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 19:32:45 +0800 Subject: [PATCH 20/31] update --- src/net/Makefile | 5 +-- src/net/line_server.cpp | 20 ++++++++++++ src/net/line_server.h | 16 ++++++++++ src/net/link.h | 1 + src/net/server.cpp | 26 +++++++++++++++ src/net/server.h | 25 +++++++++++++++ src/net/session.cpp | 1 + src/net/session.h | 4 +-- src/net/tcp_link.cpp | 2 +- src/net/tcp_link.h | 2 +- src/net/test.cpp | 12 +++++++ src/net/transport.cpp | 71 +++++++++++++++++++++-------------------- src/net/transport.h | 9 ++++-- 13 files changed, 152 insertions(+), 42 deletions(-) create mode 100644 src/net/line_server.cpp create mode 100644 src/net/line_server.h create mode 100644 src/net/server.cpp create mode 100644 src/net/server.h diff --git a/src/net/Makefile b/src/net/Makefile index cdfeacf..d021c5e 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,8 +1,9 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o link.o tcp_link.o event.o session.o transport.o \ - parser.o line_parser.o line_message.o +OBJS = fde.o link.o tcp_link.o \ + event.o parser.o session.o transport.o server.o \ + line_parser.o line_message.o line_server.o all: $(OBJS) diff --git a/src/net/line_server.cpp b/src/net/line_server.cpp new file mode 100644 index 0000000..feab18a --- /dev/null +++ b/src/net/line_server.cpp @@ -0,0 +1,20 @@ +#include "line_server.h" +#include "line_parser.h" + +LineServer::LineServer(){ +} + +LineServer::~LineServer(){ +} + +void LineServer::init(){ +} + +Session* LineServer::accept(){ + Link *link = this->link()->accept(); + if(!link){ + return NULL; + } + Session *sess = new Session(link, new LineParser()); + return sess; +} diff --git a/src/net/line_server.h b/src/net/line_server.h new file mode 100644 index 0000000..f90e5c8 --- /dev/null +++ b/src/net/line_server.h @@ -0,0 +1,16 @@ +#ifndef SIM_LINE_SERVER_H +#define SIM_LINE_SERVER_H + +#include "server.h" + +class LineServer : public Server +{ +public: + LineServer(); + ~LineServer(); + + virtual void init(); + virtual Session* accept(); +}; + +#endif diff --git a/src/net/link.h b/src/net/link.h index 25e72a6..1148e0c 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -21,6 +21,7 @@ class Link void close(); virtual int net_read() = 0; + virtual Link* accept() = 0; protected: int _fd; diff --git a/src/net/server.cpp b/src/net/server.cpp new file mode 100644 index 0000000..e449c40 --- /dev/null +++ b/src/net/server.cpp @@ -0,0 +1,26 @@ +#include "server.h" +#include +#include "tcp_link.h" +#include "util/log.h" + +Server::Server(){ + _link = NULL; +} + +Server::~Server(){ + delete _link; +} + +Link* Server::link() const{ + return _link; +} + +int Server::listen(const char *host, int port){ + TcpLink *tcp = TcpLink::listen(host, port); + if(!tcp){ + log_error("failed to listen at %s:%d, %s", host, port, strerror(errno)); + return -1; + } + this->_link = tcp; + return 0; +} diff --git a/src/net/server.h b/src/net/server.h new file mode 100644 index 0000000..7eccbfb --- /dev/null +++ b/src/net/server.h @@ -0,0 +1,25 @@ +#ifndef SIM_SERVER_H +#define SIM_SERVER_H + +#include "link.h" +#include "session.h" + +class Server +{ +public: + Server(); + virtual ~Server(); + + Link* link() const; + + virtual void init() = 0; + // 接受新连接 + virtual Session* accept() = 0; + + int listen(const char *host, int port); + +private: + Link *_link; +}; + +#endif diff --git a/src/net/session.cpp b/src/net/session.cpp index 987cf04..f80c3a2 100644 --- a/src/net/session.cpp +++ b/src/net/session.cpp @@ -1,5 +1,6 @@ #include "session.h" #include "util/log.h" +#include "line_message.h" static int id_incr = 1; diff --git a/src/net/session.h b/src/net/session.h index 29efaac..a89fcd2 100644 --- a/src/net/session.h +++ b/src/net/session.h @@ -10,14 +10,14 @@ class Session { public: Session(Link *link, Parser *parser); - ~Session(); + virtual ~Session(); int id() const; Link* link() const; Parser* parser() const; // 返回解析成功的报文数量,出错返回-1 - int parse(); + virtual int parse(); Message* recv(); diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index 956dfc7..f070ff7 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -103,7 +103,7 @@ TcpLink* TcpLink::listen(const char *ip, int port){ return NULL; } -TcpLink* TcpLink::accept(){ +Link* TcpLink::accept(){ TcpLink *link; int client_sock; struct sockaddr_in addr; diff --git a/src/net/tcp_link.h b/src/net/tcp_link.h index 3c020a1..f23b822 100644 --- a/src/net/tcp_link.h +++ b/src/net/tcp_link.h @@ -17,6 +17,7 @@ class TcpLink : public Link{ void nodelay(bool enable=true); void keepalive(bool enable=true); + virtual Link* accept(); virtual int net_read(); // int net_write(); @@ -24,7 +25,6 @@ class TcpLink : public Link{ static TcpLink* connect(const std::string &ip, int port); static TcpLink* listen(const char *ip, int port); static TcpLink* listen(const std::string &ip, int port); - TcpLink* accept(); private: diff --git a/src/net/test.cpp b/src/net/test.cpp index 4f8870b..bf3562e 100644 --- a/src/net/test.cpp +++ b/src/net/test.cpp @@ -1,6 +1,7 @@ #include "transport.h" #include "util/log.h" #include "line_message.h" +#include "line_server.h" // using namespace sim; @@ -36,7 +37,18 @@ int main(int argc, char **argv){ // } // #endif + const char *host = "127.0.0.1"; + int port = 8000; + + Server *serv = new LineServer(); + if(serv->listen(host, port) == -1){ + log_error("failed to listen at %s:%d, %s", host, port, strerror(errno)); + exit(0); + } + log_debug("server listen at %s:%d", host, port); + Transport *trans = new Transport(); + trans->add_server(serv); trans->setup(); log_debug("transport setup"); diff --git a/src/net/transport.cpp b/src/net/transport.cpp index bd1556d..d5a9e0a 100644 --- a/src/net/transport.cpp +++ b/src/net/transport.cpp @@ -1,13 +1,34 @@ #include "transport.h" #include "util/log.h" -#include "line_parser.h" -#include "line_message.h" #include "tcp_link.h" +#define FDE_NUM_COMMON 0 +#define FDE_NUM_SERVER 1 +#define FDE_NUM_CLIENT 2 + Transport::Transport(){ + _fdes = new Fdevents(); } Transport::~Transport(){ + delete _fdes; +} + +void Transport::add_server(Server *serv){ + serv->init(); + _servers.push_back(serv); + _fdes->set(serv->link()->fd(), FDEVENT_IN, FDE_NUM_SERVER, serv); +} + +void Transport::setup(){ + _fdes->set(_accept_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_accept_ids); + _fdes->set(_close_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_close_ids); + + pthread_t tid; + int err = pthread_create(&tid, NULL, &Transport::run, this); + if(err != 0){ + log_error("can't create thread: %s", strerror(err)); + } } Event Transport::wait(int timeout_ms){ @@ -103,7 +124,7 @@ void Transport::handle_accept_id(){ _opening_list.erase(sess->id()); _working_list[sess->id()] = sess; - _fdes->set(sess->link()->fd(), FDEVENT_IN, 1, sess); + _fdes->set(sess->link()->fd(), FDEVENT_IN, FDE_NUM_CLIENT, sess); } } @@ -122,29 +143,9 @@ void Transport::handle_close_id(){ } } -void Transport::setup(){ - _fdes = new Fdevents(); - - _fdes->set(_accept_ids.fd(), FDEVENT_IN, 0, &_accept_ids); - _fdes->set(_close_ids.fd(), FDEVENT_IN, 0, &_close_ids); - - pthread_t tid; - int err = pthread_create(&tid, NULL, &Transport::run, this); - if(err != 0){ - log_error("can't create thread: %s", strerror(err)); - } -} - void* Transport::run(void *arg){ Transport *trans = (Transport *)arg; const Fdevents::events_t *events; - - TcpLink *tcp_serv = TcpLink::listen("127.0.0.1", 8000); - if(!tcp_serv){ - log_error("failed to listen at 127.0.0.1:8000, %s", strerror(errno)); - } - - trans->_fdes->set(tcp_serv->fd(), FDEVENT_IN, 0, tcp_serv); while(1){ events = trans->_fdes->wait(500); @@ -155,18 +156,20 @@ void* Transport::run(void *arg){ trans->handle_accept_id(); }else if(fde->data.ptr == &trans->_close_ids){ trans->handle_close_id(); - }else if(fde->data.ptr == tcp_serv){ - Link *link = tcp_serv->accept(); - if(link){ - Session *sess = new Session(link, new LineParser()); - trans->handle_on_new(sess); - }else{ - log_error("accept return NULL"); - } }else{ - Session *sess = (Session *)fde->data.ptr; - if(sess){ // 防止已经被 fde_del - trans->handle_on_read(sess); + if(fde->data.num == FDE_NUM_SERVER){ + Server *serv = (Server *)fde->data.ptr; + Session *sess = serv->accept(); + if(sess){ + trans->handle_on_new(sess); + }else{ + log_error("accept return NULL"); + } + }else{ + Session *sess = (Session *)fde->data.ptr; + if(sess){ // 防止已经被 fde_del + trans->handle_on_read(sess); + } } } } diff --git a/src/net/transport.h b/src/net/transport.h index 39644cd..6903deb 100644 --- a/src/net/transport.h +++ b/src/net/transport.h @@ -2,9 +2,11 @@ #define SIM_TRANSPORT_H #include +#include #include "util/thread.h" #include "fde.h" #include "event.h" +#include "server.h" #include "session.h" using namespace sim; @@ -15,6 +17,9 @@ class Transport Transport(); ~Transport(); + void add_server(Server *serv); + void setup(); + Event wait(int timeout_ms); void accept(int id); @@ -23,8 +28,6 @@ class Transport Message* recv(int id); // void send(int id, Message *msg); - void setup(); - private: Mutex _mutex; @@ -45,6 +48,8 @@ class Transport Fdevents *_fdes; + std::vector _servers; + static void* run(void *arg); }; From 0b99f4f9020b03beaa1c61eda4c849480163d615 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 19:40:18 +0800 Subject: [PATCH 21/31] update --- src/line/Makefile | 3 ++- src/{net => line}/line_message.cpp | 0 src/{net => line}/line_message.h | 3 ++- src/{net => line}/line_parser.cpp | 1 - src/{net => line}/line_parser.h | 5 ++++- src/{net => line}/line_server.cpp | 0 src/{net => line}/line_server.h | 3 ++- 7 files changed, 10 insertions(+), 5 deletions(-) rename src/{net => line}/line_message.cpp (100%) rename src/{net => line}/line_message.h (83%) rename src/{net => line}/line_parser.cpp (95%) rename src/{net => line}/line_parser.h (62%) rename src/{net => line}/line_server.cpp (100%) rename src/{net => line}/line_server.h (79%) diff --git a/src/line/Makefile b/src/line/Makefile index f357cbd..3d158f9 100644 --- a/src/line/Makefile +++ b/src/line/Makefile @@ -1,9 +1,10 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS=line_message.o line_parser.o +OBJS = line_message.o line_parser.o line_server.o all: $(OBJS) + ar -cru ./libline.a ${OBJS} .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ diff --git a/src/net/line_message.cpp b/src/line/line_message.cpp similarity index 100% rename from src/net/line_message.cpp rename to src/line/line_message.cpp diff --git a/src/net/line_message.h b/src/line/line_message.h similarity index 83% rename from src/net/line_message.h rename to src/line/line_message.h index 86e86c3..3ef3c7b 100644 --- a/src/net/line_message.h +++ b/src/line/line_message.h @@ -2,7 +2,8 @@ #define SIM_LINE_MESSAGE_H #include -#include "message.h" +#include "net/message.h" +#include "util/buffer.h" class LineMessage : public Message { diff --git a/src/net/line_parser.cpp b/src/line/line_parser.cpp similarity index 95% rename from src/net/line_parser.cpp rename to src/line/line_parser.cpp index c9b3f8e..32db61a 100644 --- a/src/net/line_parser.cpp +++ b/src/line/line_parser.cpp @@ -1,6 +1,5 @@ #include "line_parser.h" #include -#include "util/buffer.h" #include "line_message.h" ParseState LineParser::parse(Buffer *buffer, Message **msg){ diff --git a/src/net/line_parser.h b/src/line/line_parser.h similarity index 62% rename from src/net/line_parser.h rename to src/line/line_parser.h index ce769ce..8c4e7b3 100644 --- a/src/net/line_parser.h +++ b/src/line/line_parser.h @@ -1,7 +1,10 @@ #ifndef SIM_LINE_PARSER_H #define SIM_LINE_PARSER_H -#include "parser.h" +#include "net/parser.h" +#include "net/message.h" +#include "net/session.h" +#include "util/buffer.h" class LineParser : public Parser { diff --git a/src/net/line_server.cpp b/src/line/line_server.cpp similarity index 100% rename from src/net/line_server.cpp rename to src/line/line_server.cpp diff --git a/src/net/line_server.h b/src/line/line_server.h similarity index 79% rename from src/net/line_server.h rename to src/line/line_server.h index f90e5c8..d292e46 100644 --- a/src/net/line_server.h +++ b/src/line/line_server.h @@ -1,7 +1,8 @@ #ifndef SIM_LINE_SERVER_H #define SIM_LINE_SERVER_H -#include "server.h" +#include "net/server.h" +#include "net/session.h" class LineServer : public Server { From f587bf9c9b5892cf0a7bd0fa544a4f2ecd1dcebc Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 19:41:55 +0800 Subject: [PATCH 22/31] update --- src/Makefile | 23 ++++--------------- src/tcp_link.h | 62 -------------------------------------------------- 2 files changed, 5 insertions(+), 80 deletions(-) delete mode 100644 src/tcp_link.h diff --git a/src/Makefile b/src/Makefile index a18d759..3282f6e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,26 +1,13 @@ include ../build_config.mk -CFLAGS += -OBJS= -LIB=libsim.a -HEADER_FILES= -UTIL_HEADERS=util/thread.h util/strings.h util/log.h util/config.h util/app.h +CFLAGS += -I . +OBJS = + +all: ${OBJS} -all: $(OBJS) - #mkdir -p $(HEADER_OUTPUT_DIR)/util - #ar -cru $(OUTPUT_DIR)/$(LIB) ${OBJS} - #cp $(HEADER_FILES) $(HEADER_OUTPUT_DIR) - #cp $(UTIL_HEADERS) $(HEADER_OUTPUT_DIR)/util - -fde.o: fde.h fde.cpp fde_select.cpp fde_epoll.cpp - ${CXX} ${CFLAGS} -c fde.cpp -# log.o: util/log.h util/log.cpp -# $(CXX) ${CFLAGS} -c util/log.cpp -# config.o: util/config.h util/config.cpp -# $(CXX) ${CFLAGS} -c util/config.cpp .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ clean: - rm -rf *.o *.a *.out $(OUTPUT_DIR)/$(LIB) $(HEADER_OUTPUT_DIR) + rm -rf *.o *.a *.out diff --git a/src/tcp_link.h b/src/tcp_link.h deleted file mode 100644 index 29794ca..0000000 --- a/src/tcp_link.h +++ /dev/null @@ -1,62 +0,0 @@ - -class Link -{ -public: - int fd() const; - Buffer* buffer() const; - - virtual int net_read() = 0; - virtual int net_write() = 0; - - virtual int send(Message &msg) = 0; -}; - - -class Server -{ -public: - Link* link() const; - void proc(); -}; - -class Session -{ -public: - Link* link() const; - Parser* parser() const; - -}; - -/* -Transport: - # 监控新连接,当有新连接时返回连接 id - listen() => id, status - # 接受指定的连接 - accept(id) - # 关闭连接 - close(id) - send(id, msg) - recv() => id, msg - -Thread1: - id, status = listen(); - if(status == new){ - accept(id); - } - if(status == closed){ - close(id); - } - -Thread2: - id, msg = recv(); - resp = process(msg); - if(resp){ - send(id, resp); - } - -Thread3: - id, msg = do_business(); - send(id, msg); -*/ - - From 313bd565130e7a6ac55d662878f385fb18a1a1c9 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 19:44:04 +0800 Subject: [PATCH 23/31] update --- src/Makefile | 7 ++++++- src/{net => }/event.cpp | 0 src/{net => }/event.h | 0 src/{net => }/message.h | 0 src/net/Makefile | 9 +-------- src/{net => }/parser.cpp | 0 src/{net => }/parser.h | 0 src/{net => }/server.cpp | 0 src/{net => }/server.h | 0 src/{net => }/session.cpp | 0 src/{net => }/session.h | 0 src/{net => }/test.cpp | 0 src/{net => }/transport.cpp | 0 src/{net => }/transport.h | 0 14 files changed, 7 insertions(+), 9 deletions(-) rename src/{net => }/event.cpp (100%) rename src/{net => }/event.h (100%) rename src/{net => }/message.h (100%) rename src/{net => }/parser.cpp (100%) rename src/{net => }/parser.h (100%) rename src/{net => }/server.cpp (100%) rename src/{net => }/server.h (100%) rename src/{net => }/session.cpp (100%) rename src/{net => }/session.h (100%) rename src/{net => }/test.cpp (100%) rename src/{net => }/transport.cpp (100%) rename src/{net => }/transport.h (100%) diff --git a/src/Makefile b/src/Makefile index 3282f6e..d64a84d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,13 +1,18 @@ include ../build_config.mk CFLAGS += -I . -OBJS = +OBJS = event.o parser.o session.o transport.o server.o all: ${OBJS} .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ +test: + make clean + make + $(CXX) ${CFLAGS} test.cpp ${OBJS} ../util/libutil.a + clean: rm -rf *.o *.a *.out diff --git a/src/net/event.cpp b/src/event.cpp similarity index 100% rename from src/net/event.cpp rename to src/event.cpp diff --git a/src/net/event.h b/src/event.h similarity index 100% rename from src/net/event.h rename to src/event.h diff --git a/src/net/message.h b/src/message.h similarity index 100% rename from src/net/message.h rename to src/message.h diff --git a/src/net/Makefile b/src/net/Makefile index d021c5e..5bfd2e3 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -1,20 +1,13 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = fde.o link.o tcp_link.o \ - event.o parser.o session.o transport.o server.o \ - line_parser.o line_message.o line_server.o +OBJS = fde.o link.o tcp_link.o all: $(OBJS) .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ -test: - make clean - make - $(CXX) ${CFLAGS} test.cpp ${OBJS} ../util/libutil.a - clean: rm -rf *.o *.a *.out diff --git a/src/net/parser.cpp b/src/parser.cpp similarity index 100% rename from src/net/parser.cpp rename to src/parser.cpp diff --git a/src/net/parser.h b/src/parser.h similarity index 100% rename from src/net/parser.h rename to src/parser.h diff --git a/src/net/server.cpp b/src/server.cpp similarity index 100% rename from src/net/server.cpp rename to src/server.cpp diff --git a/src/net/server.h b/src/server.h similarity index 100% rename from src/net/server.h rename to src/server.h diff --git a/src/net/session.cpp b/src/session.cpp similarity index 100% rename from src/net/session.cpp rename to src/session.cpp diff --git a/src/net/session.h b/src/session.h similarity index 100% rename from src/net/session.h rename to src/session.h diff --git a/src/net/test.cpp b/src/test.cpp similarity index 100% rename from src/net/test.cpp rename to src/test.cpp diff --git a/src/net/transport.cpp b/src/transport.cpp similarity index 100% rename from src/net/transport.cpp rename to src/transport.cpp diff --git a/src/net/transport.h b/src/transport.h similarity index 100% rename from src/net/transport.h rename to src/transport.h From c56ba355596a7a057472ddab611288f12ff67d62 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 19:56:31 +0800 Subject: [PATCH 24/31] update --- src/Makefile | 2 +- src/line/line_message.h | 2 +- src/line/line_parser.h | 6 +++--- src/line/line_server.cpp | 1 + src/line/line_server.h | 4 ++-- src/net/Makefile | 1 + src/server.cpp | 3 ++- src/server.h | 3 ++- src/session.cpp | 2 +- src/session.h | 3 ++- src/test.cpp | 5 ++--- src/transport.cpp | 3 ++- src/transport.h | 4 +++- 13 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Makefile b/src/Makefile index d64a84d..7b5fab6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,7 +11,7 @@ all: ${OBJS} test: make clean make - $(CXX) ${CFLAGS} test.cpp ${OBJS} ../util/libutil.a + $(CXX) ${CFLAGS} test.cpp ${OBJS} util/libutil.a net/libnet.a line/libline.a clean: rm -rf *.o *.a *.out diff --git a/src/line/line_message.h b/src/line/line_message.h index 3ef3c7b..c131348 100644 --- a/src/line/line_message.h +++ b/src/line/line_message.h @@ -2,7 +2,7 @@ #define SIM_LINE_MESSAGE_H #include -#include "net/message.h" +#include "message.h" #include "util/buffer.h" class LineMessage : public Message diff --git a/src/line/line_parser.h b/src/line/line_parser.h index 8c4e7b3..6086a23 100644 --- a/src/line/line_parser.h +++ b/src/line/line_parser.h @@ -1,9 +1,9 @@ #ifndef SIM_LINE_PARSER_H #define SIM_LINE_PARSER_H -#include "net/parser.h" -#include "net/message.h" -#include "net/session.h" +#include "parser.h" +#include "message.h" +#include "session.h" #include "util/buffer.h" class LineParser : public Parser diff --git a/src/line/line_server.cpp b/src/line/line_server.cpp index feab18a..4da3dee 100644 --- a/src/line/line_server.cpp +++ b/src/line/line_server.cpp @@ -1,5 +1,6 @@ #include "line_server.h" #include "line_parser.h" +#include "net/link.h" LineServer::LineServer(){ } diff --git a/src/line/line_server.h b/src/line/line_server.h index d292e46..64a06ca 100644 --- a/src/line/line_server.h +++ b/src/line/line_server.h @@ -1,8 +1,8 @@ #ifndef SIM_LINE_SERVER_H #define SIM_LINE_SERVER_H -#include "net/server.h" -#include "net/session.h" +#include "server.h" +#include "session.h" class LineServer : public Server { diff --git a/src/net/Makefile b/src/net/Makefile index 5bfd2e3..d2691dc 100644 --- a/src/net/Makefile +++ b/src/net/Makefile @@ -4,6 +4,7 @@ CFLAGS += -I ../ OBJS = fde.o link.o tcp_link.o all: $(OBJS) + ar -cru ./libnet.a ${OBJS} .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ diff --git a/src/server.cpp b/src/server.cpp index e449c40..da2b0e4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,7 +1,8 @@ #include "server.h" #include -#include "tcp_link.h" #include "util/log.h" +#include "net/link.h" +#include "net/tcp_link.h" Server::Server(){ _link = NULL; diff --git a/src/server.h b/src/server.h index 7eccbfb..dd8cb7c 100644 --- a/src/server.h +++ b/src/server.h @@ -1,9 +1,10 @@ #ifndef SIM_SERVER_H #define SIM_SERVER_H -#include "link.h" #include "session.h" +class Link; + class Server { public: diff --git a/src/session.cpp b/src/session.cpp index f80c3a2..33bbb81 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -1,6 +1,6 @@ #include "session.h" #include "util/log.h" -#include "line_message.h" +#include "net/link.h" static int id_incr = 1; diff --git a/src/session.h b/src/session.h index a89fcd2..6dc33c4 100644 --- a/src/session.h +++ b/src/session.h @@ -2,10 +2,11 @@ #define SIM_SESSION_H #include -#include "link.h" #include "parser.h" #include "message.h" +class Link; + class Session { public: diff --git a/src/test.cpp b/src/test.cpp index bf3562e..c862869 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,7 +1,7 @@ #include "transport.h" #include "util/log.h" -#include "line_message.h" -#include "line_server.h" +#include "line/line_message.h" +#include "line/line_server.h" // using namespace sim; @@ -70,7 +70,6 @@ int main(int argc, char **argv){ log_debug("recv: %s", msg->text().c_str()); delete msg; } - usleep(100 * 1000); } } diff --git a/src/transport.cpp b/src/transport.cpp index d5a9e0a..48f2bc5 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -1,6 +1,7 @@ #include "transport.h" #include "util/log.h" -#include "tcp_link.h" +#include "net/fde.h" +#include "net/link.h" #define FDE_NUM_COMMON 0 #define FDE_NUM_SERVER 1 diff --git a/src/transport.h b/src/transport.h index 6903deb..be0f00e 100644 --- a/src/transport.h +++ b/src/transport.h @@ -4,11 +4,13 @@ #include #include #include "util/thread.h" -#include "fde.h" #include "event.h" #include "server.h" #include "session.h" +namespace sim{ + class Fdevents; +}; using namespace sim; class Transport From 5b3aebb7e5b26f686a84d80fe7b36db65766c428 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 20:00:46 +0800 Subject: [PATCH 25/31] update --- src/{ => core}/event.cpp | 0 src/{ => core}/event.h | 0 src/{ => core}/message.h | 0 src/{ => core}/parser.cpp | 0 src/{ => core}/parser.h | 0 src/{ => core}/server.cpp | 0 src/{ => core}/server.h | 0 src/{ => core}/session.cpp | 0 src/{ => core}/session.h | 0 src/{ => core}/transport.cpp | 0 src/{ => core}/transport.h | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => core}/event.cpp (100%) rename src/{ => core}/event.h (100%) rename src/{ => core}/message.h (100%) rename src/{ => core}/parser.cpp (100%) rename src/{ => core}/parser.h (100%) rename src/{ => core}/server.cpp (100%) rename src/{ => core}/server.h (100%) rename src/{ => core}/session.cpp (100%) rename src/{ => core}/session.h (100%) rename src/{ => core}/transport.cpp (100%) rename src/{ => core}/transport.h (100%) diff --git a/src/event.cpp b/src/core/event.cpp similarity index 100% rename from src/event.cpp rename to src/core/event.cpp diff --git a/src/event.h b/src/core/event.h similarity index 100% rename from src/event.h rename to src/core/event.h diff --git a/src/message.h b/src/core/message.h similarity index 100% rename from src/message.h rename to src/core/message.h diff --git a/src/parser.cpp b/src/core/parser.cpp similarity index 100% rename from src/parser.cpp rename to src/core/parser.cpp diff --git a/src/parser.h b/src/core/parser.h similarity index 100% rename from src/parser.h rename to src/core/parser.h diff --git a/src/server.cpp b/src/core/server.cpp similarity index 100% rename from src/server.cpp rename to src/core/server.cpp diff --git a/src/server.h b/src/core/server.h similarity index 100% rename from src/server.h rename to src/core/server.h diff --git a/src/session.cpp b/src/core/session.cpp similarity index 100% rename from src/session.cpp rename to src/core/session.cpp diff --git a/src/session.h b/src/core/session.h similarity index 100% rename from src/session.h rename to src/core/session.h diff --git a/src/transport.cpp b/src/core/transport.cpp similarity index 100% rename from src/transport.cpp rename to src/core/transport.cpp diff --git a/src/transport.h b/src/core/transport.h similarity index 100% rename from src/transport.h rename to src/core/transport.h From 037506f8a352cd9ce963ef279ab51b2584003aa5 Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 20:04:09 +0800 Subject: [PATCH 26/31] update --- src/Makefile | 10 ++++------ src/core/Makefile | 19 +++++++++++++++++++ src/line/line_message.h | 2 +- src/line/line_parser.h | 6 +++--- src/line/line_server.h | 4 ++-- src/test.cpp | 2 +- 6 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 src/core/Makefile diff --git a/src/Makefile b/src/Makefile index 7b5fab6..7181d95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,18 +1,16 @@ include ../build_config.mk CFLAGS += -I . -OBJS = event.o parser.o session.o transport.o server.o +OBJS = +LIBS = util/libutil.a net/libnet.a line/libline.a core/libcore.a all: ${OBJS} + make clean + $(CXX) ${CFLAGS} test.cpp ${OBJS} ${LIBS} .cpp.o: $(CXX) ${CFLAGS} -c $< -o $@ -test: - make clean - make - $(CXX) ${CFLAGS} test.cpp ${OBJS} util/libutil.a net/libnet.a line/libline.a - clean: rm -rf *.o *.a *.out diff --git a/src/core/Makefile b/src/core/Makefile new file mode 100644 index 0000000..149b8e0 --- /dev/null +++ b/src/core/Makefile @@ -0,0 +1,19 @@ +include ../../build_config.mk + +CFLAGS += -I ../ +OBJS = event.o parser.o session.o transport.o server.o + +all: ${OBJS} + ar -cru ./libcore.a ${OBJS} + +.cpp.o: + $(CXX) ${CFLAGS} -c $< -o $@ + +test: + make clean + make + $(CXX) ${CFLAGS} test.cpp ${OBJS} util/libutil.a net/libnet.a line/libline.a + +clean: + rm -rf *.o *.a *.out + diff --git a/src/line/line_message.h b/src/line/line_message.h index c131348..7812563 100644 --- a/src/line/line_message.h +++ b/src/line/line_message.h @@ -2,7 +2,7 @@ #define SIM_LINE_MESSAGE_H #include -#include "message.h" +#include "core/message.h" #include "util/buffer.h" class LineMessage : public Message diff --git a/src/line/line_parser.h b/src/line/line_parser.h index 6086a23..787d79c 100644 --- a/src/line/line_parser.h +++ b/src/line/line_parser.h @@ -1,9 +1,9 @@ #ifndef SIM_LINE_PARSER_H #define SIM_LINE_PARSER_H -#include "parser.h" -#include "message.h" -#include "session.h" +#include "core/parser.h" +#include "core/message.h" +#include "core/session.h" #include "util/buffer.h" class LineParser : public Parser diff --git a/src/line/line_server.h b/src/line/line_server.h index 64a06ca..87d7942 100644 --- a/src/line/line_server.h +++ b/src/line/line_server.h @@ -1,8 +1,8 @@ #ifndef SIM_LINE_SERVER_H #define SIM_LINE_SERVER_H -#include "server.h" -#include "session.h" +#include "core/server.h" +#include "core/session.h" class LineServer : public Server { diff --git a/src/test.cpp b/src/test.cpp index c862869..8140cab 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,5 +1,5 @@ -#include "transport.h" #include "util/log.h" +#include "core/transport.h" #include "line/line_message.h" #include "line/line_server.h" From 34c6ab36add16e984302891bcdf2e89dd00a366c Mon Sep 17 00:00:00 2001 From: ideawu Date: Tue, 31 Jul 2018 20:21:42 +0800 Subject: [PATCH 27/31] update --- src/core/Makefile | 2 +- src/core/event.cpp | 1 + src/core/event.h | 2 +- src/core/parser.h | 3 +- src/core/server.cpp | 1 + src/core/server.h | 3 +- src/core/session.cpp | 2 + src/core/session.h | 4 +- src/core/transport.h | 56 +++++------------- .../{transport.cpp => transport_impl.cpp} | 40 +++++++------ src/core/transport_impl.h | 59 +++++++++++++++++++ src/test.cpp | 3 +- 12 files changed, 108 insertions(+), 68 deletions(-) rename src/core/{transport.cpp => transport_impl.cpp} (81%) create mode 100644 src/core/transport_impl.h diff --git a/src/core/Makefile b/src/core/Makefile index 149b8e0..5bae094 100644 --- a/src/core/Makefile +++ b/src/core/Makefile @@ -1,7 +1,7 @@ include ../../build_config.mk CFLAGS += -I ../ -OBJS = event.o parser.o session.o transport.o server.o +OBJS = event.o parser.o session.o transport_impl.o server.o all: ${OBJS} ar -cru ./libcore.a ${OBJS} diff --git a/src/core/event.cpp b/src/core/event.cpp index e1da2de..20d4e90 100644 --- a/src/core/event.cpp +++ b/src/core/event.cpp @@ -1,4 +1,5 @@ #include "event.h" +#include "session.h" Event Event::new_event(Session *sess){ return Event(sess->id(), 0); diff --git a/src/core/event.h b/src/core/event.h index e9a4534..a657941 100644 --- a/src/core/event.h +++ b/src/core/event.h @@ -1,7 +1,7 @@ #ifndef SIM_EVENT_H #define SIM_EVENT_H -#include "session.h" +class Session; class Event { diff --git a/src/core/parser.h b/src/core/parser.h index 40927c2..03124b9 100644 --- a/src/core/parser.h +++ b/src/core/parser.h @@ -1,9 +1,8 @@ #ifndef SIM_PARSER_H #define SIM_PARSER_H -#include "message.h" - class Buffer; +class Message; class ParseState; class Parser diff --git a/src/core/server.cpp b/src/core/server.cpp index da2b0e4..6af1f18 100644 --- a/src/core/server.cpp +++ b/src/core/server.cpp @@ -3,6 +3,7 @@ #include "util/log.h" #include "net/link.h" #include "net/tcp_link.h" +#include "session.h" Server::Server(){ _link = NULL; diff --git a/src/core/server.h b/src/core/server.h index dd8cb7c..98c272e 100644 --- a/src/core/server.h +++ b/src/core/server.h @@ -1,9 +1,8 @@ #ifndef SIM_SERVER_H #define SIM_SERVER_H -#include "session.h" - class Link; +class Session; class Server { diff --git a/src/core/session.cpp b/src/core/session.cpp index 33bbb81..3f0528a 100644 --- a/src/core/session.cpp +++ b/src/core/session.cpp @@ -1,6 +1,8 @@ #include "session.h" #include "util/log.h" #include "net/link.h" +#include "parser.h" +#include "message.h" static int id_incr = 1; diff --git a/src/core/session.h b/src/core/session.h index 6dc33c4..fd02764 100644 --- a/src/core/session.h +++ b/src/core/session.h @@ -2,10 +2,10 @@ #define SIM_SESSION_H #include -#include "parser.h" -#include "message.h" class Link; +class Parser; +class Message; class Session { diff --git a/src/core/transport.h b/src/core/transport.h index be0f00e..cc9a235 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -1,58 +1,30 @@ #ifndef SIM_TRANSPORT_H #define SIM_TRANSPORT_H -#include -#include -#include "util/thread.h" -#include "event.h" -#include "server.h" -#include "session.h" - -namespace sim{ - class Fdevents; -}; -using namespace sim; +class Event; +class Server; +class Message; class Transport { public: - Transport(); - ~Transport(); - - void add_server(Server *serv); - void setup(); - - Event wait(int timeout_ms); - - void accept(int id); - void close(int id); + static Transport* create(); - Message* recv(int id); - // void send(int id, Message *msg); - -private: - Mutex _mutex; + virtual ~Transport(){} - std::map _working_list; - std::map _opening_list; - std::map _closing_list; + virtual void add_server(Server *serv) = 0; + virtual void setup() = 0; - Queue _events; + virtual Event wait(int timeout_ms) = 0; - Channel _accept_ids; - Channel _close_ids; + virtual void accept(int id) = 0; + virtual void close(int id) = 0; - void handle_on_new(Session *sess); - void handle_on_close(Session *sess); - void handle_on_read(Session *sess); - void handle_accept_id(); - void handle_close_id(); - - Fdevents *_fdes; - - std::vector _servers; + virtual Message* recv(int id) = 0; + // void send(int id, Message *msg); - static void* run(void *arg); +protected: + Transport(){} }; #endif diff --git a/src/core/transport.cpp b/src/core/transport_impl.cpp similarity index 81% rename from src/core/transport.cpp rename to src/core/transport_impl.cpp index 48f2bc5..dbd3c54 100644 --- a/src/core/transport.cpp +++ b/src/core/transport_impl.cpp @@ -1,4 +1,4 @@ -#include "transport.h" +#include "transport_impl.h" #include "util/log.h" #include "net/fde.h" #include "net/link.h" @@ -7,42 +7,48 @@ #define FDE_NUM_SERVER 1 #define FDE_NUM_CLIENT 2 -Transport::Transport(){ +// static +Transport* Transport::create(){ + Transport *ret = new TransportImpl(); + return ret; +} + +TransportImpl::TransportImpl(){ _fdes = new Fdevents(); } -Transport::~Transport(){ +TransportImpl::~TransportImpl(){ delete _fdes; } -void Transport::add_server(Server *serv){ +void TransportImpl::add_server(Server *serv){ serv->init(); _servers.push_back(serv); _fdes->set(serv->link()->fd(), FDEVENT_IN, FDE_NUM_SERVER, serv); } -void Transport::setup(){ +void TransportImpl::setup(){ _fdes->set(_accept_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_accept_ids); _fdes->set(_close_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_close_ids); pthread_t tid; - int err = pthread_create(&tid, NULL, &Transport::run, this); + int err = pthread_create(&tid, NULL, &TransportImpl::run, this); if(err != 0){ log_error("can't create thread: %s", strerror(err)); } } -Event Transport::wait(int timeout_ms){ +Event TransportImpl::wait(int timeout_ms){ Event event; _events.pop(&event, timeout_ms); return event; } -void Transport::accept(int id){ +void TransportImpl::accept(int id){ this->_accept_ids.push(id); } -void Transport::close(int id){ +void TransportImpl::close(int id){ Locking l(&_mutex); if(_opening_list.find(id) != _opening_list.end()){ Session *sess = _opening_list[id]; @@ -58,7 +64,7 @@ void Transport::close(int id){ this->_close_ids.push(id); } -Message* Transport::recv(int id){ +Message* TransportImpl::recv(int id){ Locking l(&_mutex); if(_working_list.find(id) != _working_list.end()){ Session *sess = _working_list[id]; @@ -67,7 +73,7 @@ Message* Transport::recv(int id){ return NULL; } -void Transport::handle_on_new(Session *sess){ +void TransportImpl::handle_on_new(Session *sess){ log_debug("on new %s", sess->link()->address().c_str()); Locking l(&_mutex); @@ -76,7 +82,7 @@ void Transport::handle_on_new(Session *sess){ this->_events.push(Event::new_event(sess)); } -void Transport::handle_on_close(Session *sess){ +void TransportImpl::handle_on_close(Session *sess){ int id = sess->id(); log_debug("on close %s", sess->link()->address().c_str()); Locking l(&_mutex); @@ -89,7 +95,7 @@ void Transport::handle_on_close(Session *sess){ } } -void Transport::handle_on_read(Session *sess){ +void TransportImpl::handle_on_read(Session *sess){ // log_debug("net read %s", sess->link()->address().c_str()); bool error = false; @@ -114,7 +120,7 @@ void Transport::handle_on_read(Session *sess){ } } -void Transport::handle_accept_id(){ +void TransportImpl::handle_accept_id(){ int id; _accept_ids.pop(&id); @@ -129,7 +135,7 @@ void Transport::handle_accept_id(){ } } -void Transport::handle_close_id(){ +void TransportImpl::handle_close_id(){ int id; _close_ids.pop(&id); @@ -144,8 +150,8 @@ void Transport::handle_close_id(){ } } -void* Transport::run(void *arg){ - Transport *trans = (Transport *)arg; +void* TransportImpl::run(void *arg){ + TransportImpl *trans = (TransportImpl *)arg; const Fdevents::events_t *events; while(1){ diff --git a/src/core/transport_impl.h b/src/core/transport_impl.h new file mode 100644 index 0000000..3a43530 --- /dev/null +++ b/src/core/transport_impl.h @@ -0,0 +1,59 @@ +#ifndef SIM_TRANSPORT_IMPL_H +#define SIM_TRANSPORT_IMPL_H + +#include +#include +#include "util/thread.h" +#include "transport.h" +#include "event.h" +#include "server.h" +#include "session.h" + +namespace sim{ + class Fdevents; +}; +using namespace sim; + +class TransportImpl : public Transport +{ +public: + TransportImpl(); + ~TransportImpl(); + + virtual void add_server(Server *serv); + virtual void setup(); + + virtual Event wait(int timeout_ms); + + virtual void accept(int id); + virtual void close(int id); + + virtual Message* recv(int id); + // void send(int id, Message *msg); + +private: + Mutex _mutex; + + std::map _working_list; + std::map _opening_list; + std::map _closing_list; + + Queue _events; + + Channel _accept_ids; + Channel _close_ids; + + void handle_on_new(Session *sess); + void handle_on_close(Session *sess); + void handle_on_read(Session *sess); + void handle_accept_id(); + void handle_close_id(); + + Fdevents *_fdes; + + std::vector _servers; + + static void* run(void *arg); +}; + +#endif diff --git a/src/test.cpp b/src/test.cpp index 8140cab..10c2153 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,4 +1,5 @@ #include "util/log.h" +#include "core/event.h" #include "core/transport.h" #include "line/line_message.h" #include "line/line_server.h" @@ -47,7 +48,7 @@ int main(int argc, char **argv){ } log_debug("server listen at %s:%d", host, port); - Transport *trans = new Transport(); + Transport *trans = Transport::create(); trans->add_server(serv); trans->setup(); log_debug("transport setup"); From 73a884267204f37384822ad604c1d6404619b724 Mon Sep 17 00:00:00 2001 From: ideawu Date: Wed, 1 Aug 2018 13:20:45 +0800 Subject: [PATCH 28/31] update --- src/core/message.h | 2 +- src/core/session.cpp | 29 ++++++++++++++-- src/core/session.h | 10 ++++-- src/core/transport.h | 2 +- src/core/transport_impl.cpp | 66 +++++++++++++++++++++++++++++++++++-- src/core/transport_impl.h | 5 ++- src/http/Makefile | 14 ++++++++ src/line/line_message.cpp | 9 +++-- src/line/line_message.h | 2 +- src/net/link.cpp | 14 +++++--- src/net/link.h | 9 +++-- src/net/tcp_link.cpp | 34 ++++++++++++++++++- src/net/tcp_link.h | 2 +- src/test.cpp | 15 ++++++--- src/util/buffer.cpp | 4 +++ src/util/buffer.h | 1 + 16 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 src/http/Makefile diff --git a/src/core/message.h b/src/core/message.h index 6eee55d..1727302 100644 --- a/src/core/message.h +++ b/src/core/message.h @@ -7,7 +7,7 @@ class Message { public: virtual ~Message(){} - virtual Buffer* encode() = 0; + virtual int encode(Buffer *buffer) = 0; }; #endif diff --git a/src/core/session.cpp b/src/core/session.cpp index 3f0528a..2ca844b 100644 --- a/src/core/session.cpp +++ b/src/core/session.cpp @@ -37,11 +37,19 @@ Parser* Session::parser() const{ return _parser; } -int Session::parse(){ +const std::list* Session::input() const{ + return &_input; +} + +const std::list* Session::output() const{ + return &_output; +} + +int Session::parse_input(){ int ret = 0; while(1){ Message *msg; - ParseState s = _parser->parse(_link->buffer(), &msg); + ParseState s = _parser->parse(_link->input(), &msg); if(s.ready()){ _input.push_back(msg); ret ++; @@ -51,7 +59,18 @@ int Session::parse(){ break; } } - log_debug("received %d message(s)", ret); + return ret; +} + +int Session::encode_output(){ + int ret = 0; + while(!_output.empty()){ + Message *msg = _output.front(); + _output.pop_front(); + msg->encode(_link->output()); + delete msg; + ret ++; + } return ret; } @@ -63,3 +82,7 @@ Message* Session::recv(){ _input.pop_front(); return msg; } + +void Session::send(Message *msg){ + _output.push_back(msg); +} diff --git a/src/core/session.h b/src/core/session.h index fd02764..2d79fa7 100644 --- a/src/core/session.h +++ b/src/core/session.h @@ -17,10 +17,16 @@ class Session Link* link() const; Parser* parser() const; - // 返回解析成功的报文数量,出错返回-1 - virtual int parse(); + const std::list* input() const; + const std::list* output() const; + + // 返回解析成功的要接收的报文的数量,出错返回-1 + virtual int parse_input(); + // 返回编码成功的要发送的报文的数量,出错返回-1 + virtual int encode_output(); Message* recv(); + void send(Message *msg); private: int _id; diff --git a/src/core/transport.h b/src/core/transport.h index cc9a235..8ed1229 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -21,7 +21,7 @@ class Transport virtual void close(int id) = 0; virtual Message* recv(int id) = 0; - // void send(int id, Message *msg); + virtual void send(int id, Message *msg) = 0; protected: Transport(){} diff --git a/src/core/transport_impl.cpp b/src/core/transport_impl.cpp index dbd3c54..c101108 100644 --- a/src/core/transport_impl.cpp +++ b/src/core/transport_impl.cpp @@ -30,6 +30,7 @@ void TransportImpl::add_server(Server *serv){ void TransportImpl::setup(){ _fdes->set(_accept_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_accept_ids); _fdes->set(_close_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_close_ids); + _fdes->set(_send_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_send_ids); pthread_t tid; int err = pthread_create(&tid, NULL, &TransportImpl::run, this); @@ -73,6 +74,17 @@ Message* TransportImpl::recv(int id){ return NULL; } +void TransportImpl::send(int id, Message *msg){ + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + Session *sess = _working_list[id]; + sess->send(msg); + + // log_debug("output.size %d", sess->output()->size()); + this->_send_ids.push(id); + } +} + void TransportImpl::handle_on_new(Session *sess){ log_debug("on new %s", sess->link()->address().c_str()); @@ -104,11 +116,12 @@ void TransportImpl::handle_on_read(Session *sess){ error = true; }else{ Locking l(&_mutex); - int num = sess->parse(); + int num = sess->parse_input(); if(num == -1){ log_debug("parse error!"); error = true; }else{ + log_debug("parsed %d message(s)", num); for(int i=0; i_events.push(Event::read_event(sess)); } @@ -120,6 +133,35 @@ void TransportImpl::handle_on_read(Session *sess){ } } +void TransportImpl::handle_on_write(Session *sess){ + bool error = false; + + { + Locking l(&_mutex); + if(!sess->output()->empty()){ + int num = sess->encode_output(); + if(num == -1){ + log_debug("encode error!"); + error = true; + }else{ + log_debug("encoded %d message(s)", num); + } + } + } + + int ret = sess->link()->net_write(); + if(ret == 0){ + log_debug("fde.clr(%d, OUT)", sess->id()); + _fdes->clr(sess->link()->fd(), FDEVENT_OUT); + }else if(ret == -1){ + error = true; + } + + if(error){ + this->handle_on_close(sess); + } +} + void TransportImpl::handle_accept_id(){ int id; _accept_ids.pop(&id); @@ -150,6 +192,20 @@ void TransportImpl::handle_close_id(){ } } +void TransportImpl::handle_send_id(){ + int id; + _send_ids.pop(&id); + + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + Session *sess = _working_list[id]; + if(!sess->output()->empty() && !_fdes->isset(sess->link()->fd(), FDEVENT_OUT)){ + log_debug("fde.set(%d, OUT)", sess->id()); + _fdes->set(sess->link()->fd(), FDEVENT_OUT, FDE_NUM_CLIENT, sess); + } + } +} + void* TransportImpl::run(void *arg){ TransportImpl *trans = (TransportImpl *)arg; const Fdevents::events_t *events; @@ -163,6 +219,8 @@ void* TransportImpl::run(void *arg){ trans->handle_accept_id(); }else if(fde->data.ptr == &trans->_close_ids){ trans->handle_close_id(); + }else if(fde->data.ptr == &trans->_send_ids){ + trans->handle_send_id(); }else{ if(fde->data.num == FDE_NUM_SERVER){ Server *serv = (Server *)fde->data.ptr; @@ -175,7 +233,11 @@ void* TransportImpl::run(void *arg){ }else{ Session *sess = (Session *)fde->data.ptr; if(sess){ // 防止已经被 fde_del - trans->handle_on_read(sess); + if(fde->events & FDEVENT_IN){ + trans->handle_on_read(sess); + }else if(fde->events & FDEVENT_OUT){ + trans->handle_on_write(sess); + } } } } diff --git a/src/core/transport_impl.h b/src/core/transport_impl.h index 3a43530..bdf3590 100644 --- a/src/core/transport_impl.h +++ b/src/core/transport_impl.h @@ -29,7 +29,7 @@ class TransportImpl : public Transport virtual void close(int id); virtual Message* recv(int id); - // void send(int id, Message *msg); + virtual void send(int id, Message *msg); private: Mutex _mutex; @@ -42,12 +42,15 @@ class TransportImpl : public Transport Channel _accept_ids; Channel _close_ids; + Channel _send_ids; void handle_on_new(Session *sess); void handle_on_close(Session *sess); void handle_on_read(Session *sess); + void handle_on_write(Session *sess); void handle_accept_id(); void handle_close_id(); + void handle_send_id(); Fdevents *_fdes; diff --git a/src/http/Makefile b/src/http/Makefile new file mode 100644 index 0000000..8c3f543 --- /dev/null +++ b/src/http/Makefile @@ -0,0 +1,14 @@ +include ../../build_config.mk + +CFLAGS += -I ../ +OBJS = + +all: $(OBJS) + ar -cru ./libhttp.a ${OBJS} + +.cpp.o: + $(CXX) ${CFLAGS} -c $< -o $@ + +clean: + rm -rf *.o *.a *.out + diff --git a/src/line/line_message.cpp b/src/line/line_message.cpp index 7b16eeb..067f8d5 100644 --- a/src/line/line_message.cpp +++ b/src/line/line_message.cpp @@ -8,9 +8,8 @@ void LineMessage::text(const std::string &s){ _text = s; } -Buffer* LineMessage::encode(){ - Buffer *buf = new Buffer(); - buf->append(_text.data(), _text.size()); - buf->append("\n", 1); - return buf; +int LineMessage::encode(Buffer *buffer){ + buffer->append(_text.data(), _text.size()); + buffer->append("\n", 1); + return _text.size() + 1; } diff --git a/src/line/line_message.h b/src/line/line_message.h index 7812563..1325643 100644 --- a/src/line/line_message.h +++ b/src/line/line_message.h @@ -11,7 +11,7 @@ class LineMessage : public Message std::string text() const; void text(const std::string &s); - virtual Buffer* encode(); + virtual int encode(Buffer *buffer); private: std::string _text; diff --git a/src/net/link.cpp b/src/net/link.cpp index 5749edf..3cae8d5 100644 --- a/src/net/link.cpp +++ b/src/net/link.cpp @@ -6,20 +6,26 @@ Link::Link(){ _fd = -1; _nonblock = false; - _buffer = new Buffer(); + _input = new Buffer(); + _output = new Buffer(); } Link::~Link(){ this->close(); - delete _buffer; + delete _input; + delete _output; } int Link::fd() const{ return _fd; } -Buffer* Link::buffer() const{ - return _buffer; +Buffer* Link::input() const{ + return _input; +} + +Buffer* Link::output() const{ + return _output; } std::string Link::address() const{ diff --git a/src/net/link.h b/src/net/link.h index 1148e0c..d0eddf6 100644 --- a/src/net/link.h +++ b/src/net/link.h @@ -13,19 +13,22 @@ class Link virtual ~Link(); int fd() const; - Buffer* buffer() const; + Buffer* input() const; + Buffer* output() const; std::string address() const; bool nonblock() const; void nonblock(bool enable); void close(); - virtual int net_read() = 0; virtual Link* accept() = 0; + virtual int net_read() = 0; + virtual int net_write() = 0; protected: int _fd; - Buffer* _buffer; + Buffer* _input; + Buffer* _output; std::string _address; private: diff --git a/src/net/tcp_link.cpp b/src/net/tcp_link.cpp index f070ff7..60fdfa6 100644 --- a/src/net/tcp_link.cpp +++ b/src/net/tcp_link.cpp @@ -158,7 +158,7 @@ int TcpLink::net_read(){ } ret += len; - _buffer->append(buf, len); + _input->append(buf, len); } if(!nonblock()){ break; @@ -168,4 +168,36 @@ int TcpLink::net_read(){ return ret; } +int TcpLink::net_write(){ + int ret = 0; + int want; + while((want = _output->size()) > 0){ + // test + // want = 1; + int len = ::write(fd(), _output->data(), want); + if(len == -1){ + if(errno == EINTR){ + continue; + }else if(errno == EWOULDBLOCK){ + break; + }else{ + //log_debug("fd: %d, write: -1, error: %s", sock, strerror(errno)); + return -1; + } + }else{ + //log_debug("fd: %d, want: %d, write: %d", sock, want, len); + if(len == 0){ + // ? + break; + } + ret += len; + _output->remove(len); + } + if(!nonblock()){ + break; + } + } + return ret; +} + // }; // namespace sim diff --git a/src/net/tcp_link.h b/src/net/tcp_link.h index f23b822..63417ad 100644 --- a/src/net/tcp_link.h +++ b/src/net/tcp_link.h @@ -19,7 +19,7 @@ class TcpLink : public Link{ virtual Link* accept(); virtual int net_read(); - // int net_write(); + virtual int net_write(); static TcpLink* connect(const char *ip, int port); static TcpLink* connect(const std::string &ip, int port); diff --git a/src/test.cpp b/src/test.cpp index 10c2153..93a7402 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -63,13 +63,20 @@ int main(int argc, char **argv){ trans->close(event.id()); }else if(event.is_read()){ // log_debug("read"); - LineMessage *msg = (LineMessage *)trans->recv(event.id()); - if(!msg){ + LineMessage *req = (LineMessage *)trans->recv(event.id()); + if(!req){ // do nothing, the close event will finally be triggered log_debug("recv NULL msg, detect session closed"); }else{ - log_debug("recv: %s", msg->text().c_str()); - delete msg; + log_debug("recv: %s", req->text().c_str()); + + std::string text = "req="; + text.append(req->text()); + LineMessage *resp = new LineMessage(); + resp->text(text); + trans->send(event.id(), resp); + + delete req; } } } diff --git a/src/util/buffer.cpp b/src/util/buffer.cpp index a28ca73..66fdb69 100644 --- a/src/util/buffer.cpp +++ b/src/util/buffer.cpp @@ -12,6 +12,10 @@ Buffer::~Buffer(){ free(_buf); } +bool Buffer::empty() const{ + return _size == 0; +} + int Buffer::size() const{ return _size; } diff --git a/src/util/buffer.h b/src/util/buffer.h index 56c0ea6..72a3bd6 100644 --- a/src/util/buffer.h +++ b/src/util/buffer.h @@ -7,6 +7,7 @@ class Buffer Buffer(); ~Buffer(); + bool empty() const; int size() const; char* data(); From 1169bb763ef7cc023ebe5e4986c269d2bcc25e70 Mon Sep 17 00:00:00 2001 From: ideawu Date: Wed, 1 Aug 2018 15:54:05 +0800 Subject: [PATCH 29/31] update --- src/core/transport_impl.cpp | 95 +++++++++++++++++++------------------ src/test.cpp | 2 + 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/core/transport_impl.cpp b/src/core/transport_impl.cpp index c101108..c766959 100644 --- a/src/core/transport_impl.cpp +++ b/src/core/transport_impl.cpp @@ -74,39 +74,6 @@ Message* TransportImpl::recv(int id){ return NULL; } -void TransportImpl::send(int id, Message *msg){ - Locking l(&_mutex); - if(_working_list.find(id) != _working_list.end()){ - Session *sess = _working_list[id]; - sess->send(msg); - - // log_debug("output.size %d", sess->output()->size()); - this->_send_ids.push(id); - } -} - -void TransportImpl::handle_on_new(Session *sess){ - log_debug("on new %s", sess->link()->address().c_str()); - - Locking l(&_mutex); - _opening_list[sess->id()] = sess; - - this->_events.push(Event::new_event(sess)); -} - -void TransportImpl::handle_on_close(Session *sess){ - int id = sess->id(); - log_debug("on close %s", sess->link()->address().c_str()); - Locking l(&_mutex); - if(_working_list.find(id) != _working_list.end()){ - _working_list.erase(sess->id()); - _closing_list[sess->id()] = sess; - - _fdes->del(sess->link()->fd()); - this->_events.push(Event::close_event(sess)); - } -} - void TransportImpl::handle_on_read(Session *sess){ // log_debug("net read %s", sess->link()->address().c_str()); @@ -133,6 +100,32 @@ void TransportImpl::handle_on_read(Session *sess){ } } +void TransportImpl::send(int id, Message *msg){ + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + Session *sess = _working_list[id]; + sess->send(msg); + + // log_debug("output.size %d", sess->output()->size()); + this->_send_ids.push(id); + } +} + +void TransportImpl::handle_send_id(){ + Locking l(&_mutex); + + int id; + _send_ids.pop(&id); + + if(_working_list.find(id) != _working_list.end()){ + Session *sess = _working_list[id]; + if(!sess->output()->empty() && !_fdes->isset(sess->link()->fd(), FDEVENT_OUT)){ + log_debug("fde.set(%d, OUT)", sess->id()); + _fdes->set(sess->link()->fd(), FDEVENT_OUT, FDE_NUM_CLIENT, sess); + } + } +} + void TransportImpl::handle_on_write(Session *sess){ bool error = false; @@ -162,6 +155,28 @@ void TransportImpl::handle_on_write(Session *sess){ } } +void TransportImpl::handle_on_new(Session *sess){ + log_debug("on new %s", sess->link()->address().c_str()); + + Locking l(&_mutex); + _opening_list[sess->id()] = sess; + + this->_events.push(Event::new_event(sess)); +} + +void TransportImpl::handle_on_close(Session *sess){ + int id = sess->id(); + log_debug("on close %s", sess->link()->address().c_str()); + Locking l(&_mutex); + if(_working_list.find(id) != _working_list.end()){ + _working_list.erase(sess->id()); + _closing_list[sess->id()] = sess; + + _fdes->del(sess->link()->fd()); + this->_events.push(Event::close_event(sess)); + } +} + void TransportImpl::handle_accept_id(){ int id; _accept_ids.pop(&id); @@ -192,20 +207,6 @@ void TransportImpl::handle_close_id(){ } } -void TransportImpl::handle_send_id(){ - int id; - _send_ids.pop(&id); - - Locking l(&_mutex); - if(_working_list.find(id) != _working_list.end()){ - Session *sess = _working_list[id]; - if(!sess->output()->empty() && !_fdes->isset(sess->link()->fd(), FDEVENT_OUT)){ - log_debug("fde.set(%d, OUT)", sess->id()); - _fdes->set(sess->link()->fd(), FDEVENT_OUT, FDE_NUM_CLIENT, sess); - } - } -} - void* TransportImpl::run(void *arg){ TransportImpl *trans = (TransportImpl *)arg; const Fdevents::events_t *events; diff --git a/src/test.cpp b/src/test.cpp index 93a7402..6df00fa 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -23,6 +23,8 @@ void signal_handler(int sig){ } int main(int argc, char **argv){ + // set_log_level("error"); + signal(SIGPIPE, SIG_IGN); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); From 1696b8c06025dc6e6191c3866cc57764c6d74f55 Mon Sep 17 00:00:00 2001 From: ideawu Date: Thu, 2 Aug 2018 15:29:11 +0800 Subject: [PATCH 30/31] update --- src/core/transport.h | 11 +++-- src/core/transport_impl.cpp | 84 +++++++++++++++++-------------------- src/core/transport_impl.h | 9 ++-- src/net/fde.h | 2 +- src/test.cpp | 48 +++++++++++---------- 5 files changed, 76 insertions(+), 78 deletions(-) diff --git a/src/core/transport.h b/src/core/transport.h index 8ed1229..4e6438f 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -1,6 +1,8 @@ #ifndef SIM_TRANSPORT_H #define SIM_TRANSPORT_H +#include + class Event; class Server; class Message; @@ -13,14 +15,17 @@ class Transport virtual ~Transport(){} virtual void add_server(Server *serv) = 0; - virtual void setup() = 0; + virtual void init() = 0; - virtual Event wait(int timeout_ms) = 0; + virtual const std::vector* wait(int timeout_ms) = 0; + // multi-thread safe virtual void accept(int id) = 0; + // multi-thread safe virtual void close(int id) = 0; - + // multi-thread safe virtual Message* recv(int id) = 0; + // multi-thread safe virtual void send(int id, Message *msg) = 0; protected: diff --git a/src/core/transport_impl.cpp b/src/core/transport_impl.cpp index c766959..c15d53b 100644 --- a/src/core/transport_impl.cpp +++ b/src/core/transport_impl.cpp @@ -27,22 +27,16 @@ void TransportImpl::add_server(Server *serv){ _fdes->set(serv->link()->fd(), FDEVENT_IN, FDE_NUM_SERVER, serv); } -void TransportImpl::setup(){ +void TransportImpl::init(){ _fdes->set(_accept_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_accept_ids); _fdes->set(_close_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_close_ids); _fdes->set(_send_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_send_ids); - pthread_t tid; - int err = pthread_create(&tid, NULL, &TransportImpl::run, this); - if(err != 0){ - log_error("can't create thread: %s", strerror(err)); - } -} - -Event TransportImpl::wait(int timeout_ms){ - Event event; - _events.pop(&event, timeout_ms); - return event; + // pthread_t tid; + // int err = pthread_create(&tid, NULL, &TransportImpl::run, this); + // if(err != 0){ + // log_error("can't create thread: %s", strerror(err)); + // } } void TransportImpl::accept(int id){ @@ -90,7 +84,7 @@ void TransportImpl::handle_on_read(Session *sess){ }else{ log_debug("parsed %d message(s)", num); for(int i=0; i_events.push(Event::read_event(sess)); + this->_events.push_back(Event::read_event(sess)); } } } @@ -161,7 +155,7 @@ void TransportImpl::handle_on_new(Session *sess){ Locking l(&_mutex); _opening_list[sess->id()] = sess; - this->_events.push(Event::new_event(sess)); + this->_events.push_back(Event::new_event(sess)); } void TransportImpl::handle_on_close(Session *sess){ @@ -173,7 +167,7 @@ void TransportImpl::handle_on_close(Session *sess){ _closing_list[sess->id()] = sess; _fdes->del(sess->link()->fd()); - this->_events.push(Event::close_event(sess)); + this->_events.push_back(Event::close_event(sess)); } } @@ -207,42 +201,40 @@ void TransportImpl::handle_close_id(){ } } -void* TransportImpl::run(void *arg){ - TransportImpl *trans = (TransportImpl *)arg; - const Fdevents::events_t *events; - - while(1){ - events = trans->_fdes->wait(500); - - for(int i=0; i<(int)events->size(); i++){ - const Fdevent *fde = events->at(i); - if(fde->data.ptr == &trans->_accept_ids){ - trans->handle_accept_id(); - }else if(fde->data.ptr == &trans->_close_ids){ - trans->handle_close_id(); - }else if(fde->data.ptr == &trans->_send_ids){ - trans->handle_send_id(); +const std::vector* TransportImpl::wait(int timeout_ms){ + _events.clear(); + + const Fdevents::events_t *events = _fdes->wait(timeout_ms); + for(int i=0; i<(int)events->size(); i++){ + const Fdevent *fde = events->at(i); + if(fde->data.ptr == &this->_accept_ids){ + this->handle_accept_id(); + }else if(fde->data.ptr == &this->_close_ids){ + this->handle_close_id(); + }else if(fde->data.ptr == &this->_send_ids){ + this->handle_send_id(); + }else{ + if(fde->data.num == FDE_NUM_SERVER){ + Server *serv = (Server *)fde->data.ptr; + Session *sess = serv->accept(); + if(sess){ + this->handle_on_new(sess); + }else{ + log_error("accept return NULL"); + } }else{ - if(fde->data.num == FDE_NUM_SERVER){ - Server *serv = (Server *)fde->data.ptr; - Session *sess = serv->accept(); - if(sess){ - trans->handle_on_new(sess); - }else{ - log_error("accept return NULL"); + Session *sess = (Session *)fde->data.ptr; + if(sess){ // 防止已经被 fde_del + if(fde->events & FDEVENT_IN){ + this->handle_on_read(sess); } - }else{ - Session *sess = (Session *)fde->data.ptr; - if(sess){ // 防止已经被 fde_del - if(fde->events & FDEVENT_IN){ - trans->handle_on_read(sess); - }else if(fde->events & FDEVENT_OUT){ - trans->handle_on_write(sess); - } + if(fde->events & FDEVENT_OUT){ + this->handle_on_write(sess); } } } } } - return NULL; + + return &_events; } diff --git a/src/core/transport_impl.h b/src/core/transport_impl.h index bdf3590..4126c4e 100644 --- a/src/core/transport_impl.h +++ b/src/core/transport_impl.h @@ -21,13 +21,12 @@ class TransportImpl : public Transport ~TransportImpl(); virtual void add_server(Server *serv); - virtual void setup(); + virtual void init(); - virtual Event wait(int timeout_ms); + virtual const std::vector* wait(int timeout_ms); virtual void accept(int id); virtual void close(int id); - virtual Message* recv(int id); virtual void send(int id, Message *msg); @@ -38,7 +37,7 @@ class TransportImpl : public Transport std::map _opening_list; std::map _closing_list; - Queue _events; + std::vector _events; Channel _accept_ids; Channel _close_ids; @@ -55,8 +54,6 @@ class TransportImpl : public Transport Fdevents *_fdes; std::vector _servers; - - static void* run(void *arg); }; #endif diff --git a/src/net/fde.h b/src/net/fde.h index dc2432e..fddd428 100644 --- a/src/net/fde.h +++ b/src/net/fde.h @@ -57,7 +57,7 @@ struct Fdevent{ class Fdevents{ public: - typedef std::vector events_t; + typedef std::vector events_t; private: #ifdef HAVE_EPOLL static const int MAX_FDS = 8 * 1024; diff --git a/src/test.cpp b/src/test.cpp index 6df00fa..f0da737 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -52,33 +52,37 @@ int main(int argc, char **argv){ Transport *trans = Transport::create(); trans->add_server(serv); - trans->setup(); + trans->init(); log_debug("transport setup"); while(!quit){ - Event event = trans->wait(200); - if(event.is_new()){ - log_debug("accept"); - trans->accept(event.id()); - }else if(event.is_close()){ - log_debug("close"); - trans->close(event.id()); - }else if(event.is_read()){ - // log_debug("read"); - LineMessage *req = (LineMessage *)trans->recv(event.id()); - if(!req){ - // do nothing, the close event will finally be triggered - log_debug("recv NULL msg, detect session closed"); - }else{ - log_debug("recv: %s", req->text().c_str()); + const std::vector *events = trans->wait(200); + for(int i=0; i<(int)events->size(); i++){ + Event event = events->at(i); + + if(event.is_new()){ + log_debug("accept"); + trans->accept(event.id()); + }else if(event.is_close()){ + log_debug("close"); + trans->close(event.id()); + }else if(event.is_read()){ + // log_debug("read"); + LineMessage *req = (LineMessage *)trans->recv(event.id()); + if(!req){ + // do nothing, the close event will finally be triggered + log_debug("recv NULL msg, detect session closed"); + }else{ + log_debug("recv: %s", req->text().c_str()); - std::string text = "req="; - text.append(req->text()); - LineMessage *resp = new LineMessage(); - resp->text(text); - trans->send(event.id(), resp); + std::string text = "req="; + text.append(req->text()); + LineMessage *resp = new LineMessage(); + resp->text(text); + trans->send(event.id(), resp); - delete req; + delete req; + } } } } From 5fee2ea1889594198c2f41b484d0a80cf0e715eb Mon Sep 17 00:00:00 2001 From: ideawu Date: Thu, 2 Aug 2018 16:12:05 +0800 Subject: [PATCH 31/31] update --- src/core/transport_impl.cpp | 13 ++---- src/core/worker.h | 84 +++++++++++++++++++++++++++++++++++++ src/test.cpp | 50 +++++++++++++++------- 3 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 src/core/worker.h diff --git a/src/core/transport_impl.cpp b/src/core/transport_impl.cpp index c15d53b..9009d2d 100644 --- a/src/core/transport_impl.cpp +++ b/src/core/transport_impl.cpp @@ -32,11 +32,6 @@ void TransportImpl::init(){ _fdes->set(_close_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_close_ids); _fdes->set(_send_ids.fd(), FDEVENT_IN, FDE_NUM_COMMON, &_send_ids); - // pthread_t tid; - // int err = pthread_create(&tid, NULL, &TransportImpl::run, this); - // if(err != 0){ - // log_error("can't create thread: %s", strerror(err)); - // } } void TransportImpl::accept(int id){ @@ -82,7 +77,7 @@ void TransportImpl::handle_on_read(Session *sess){ log_debug("parse error!"); error = true; }else{ - log_debug("parsed %d message(s)", num); + // log_debug("parsed %d message(s)", num); for(int i=0; i_events.push_back(Event::read_event(sess)); } @@ -114,7 +109,7 @@ void TransportImpl::handle_send_id(){ if(_working_list.find(id) != _working_list.end()){ Session *sess = _working_list[id]; if(!sess->output()->empty() && !_fdes->isset(sess->link()->fd(), FDEVENT_OUT)){ - log_debug("fde.set(%d, OUT)", sess->id()); + // log_debug("fde.set(%d, OUT)", sess->id()); _fdes->set(sess->link()->fd(), FDEVENT_OUT, FDE_NUM_CLIENT, sess); } } @@ -131,14 +126,14 @@ void TransportImpl::handle_on_write(Session *sess){ log_debug("encode error!"); error = true; }else{ - log_debug("encoded %d message(s)", num); + // log_debug("encoded %d message(s)", num); } } } int ret = sess->link()->net_write(); if(ret == 0){ - log_debug("fde.clr(%d, OUT)", sess->id()); + // log_debug("fde.clr(%d, OUT)", sess->id()); _fdes->clr(sess->link()->fd(), FDEVENT_OUT); }else if(ret == -1){ error = true; diff --git a/src/core/worker.h b/src/core/worker.h new file mode 100644 index 0000000..aa40bb0 --- /dev/null +++ b/src/core/worker.h @@ -0,0 +1,84 @@ +#ifndef SIM_WORKER_H +#define SIM_WORKER_H + +#include "util/thread.h" +#include "util/log.h" + +template +class Worker +{ +public: + Worker(); + virtual ~Worker(); + + void start(int num=1); + void stop(); + void add_task(T task); + + virtual void process(T task) = 0; + +private: + Queue _tasks; + Mutex _mutex; + bool _quit; + int _num; + static void* run(void *arg); +}; + +template +Worker::Worker(){ +} + +template +Worker::~Worker(){ +} + +template +void Worker::add_task(T task){ + _tasks.push(task); +} + +template +void Worker::start(int num){ + _quit = false; + _num = num; + for(int i=0; i +void Worker::stop(){ + _quit = true; + + for(int i=0; i<20; i++){ + usleep(10 * 1000); + Locking l(&_mutex); + if(_num == 0){ + break; + } + } +} + +template +void* Worker::run(void *arg){ + Worker *worker = (Worker *)arg; + + while(!worker->_quit){ + T event; + int ret = worker->_tasks.pop(&event, 20); + if(ret == 1){ + worker->process(event); + } + } + + Locking l(&worker->_mutex); + worker->_num --; + + return NULL; +} +#endif diff --git a/src/test.cpp b/src/test.cpp index f0da737..752e089 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,6 +1,7 @@ #include "util/log.h" #include "core/event.h" #include "core/transport.h" +#include "core/worker.h" #include "line/line_message.h" #include "line/line_server.h" @@ -22,6 +23,32 @@ void signal_handler(int sig){ } } +class TestWorker : public Worker +{ +public: + Transport *trans; + + virtual void process(Event event){ + // log_debug("read"); + LineMessage *req = (LineMessage *)trans->recv(event.id()); + if(!req){ + // do nothing, the close event will finally be triggered + log_debug("recv NULL msg, detect session closed"); + return; + } + + log_debug("recv: %s", req->text().c_str()); + + std::string text = "req="; + text.append(req->text()); + LineMessage *resp = new LineMessage(); + resp->text(text); + trans->send(event.id(), resp); + + delete req; + } +}; + int main(int argc, char **argv){ // set_log_level("error"); @@ -54,6 +81,10 @@ int main(int argc, char **argv){ trans->add_server(serv); trans->init(); log_debug("transport setup"); + + TestWorker worker; + worker.trans = trans; + worker.start(10); while(!quit){ const std::vector *events = trans->wait(200); @@ -67,25 +98,12 @@ int main(int argc, char **argv){ log_debug("close"); trans->close(event.id()); }else if(event.is_read()){ - // log_debug("read"); - LineMessage *req = (LineMessage *)trans->recv(event.id()); - if(!req){ - // do nothing, the close event will finally be triggered - log_debug("recv NULL msg, detect session closed"); - }else{ - log_debug("recv: %s", req->text().c_str()); - - std::string text = "req="; - text.append(req->text()); - LineMessage *resp = new LineMessage(); - resp->text(text); - trans->send(event.id(), resp); - - delete req; - } + worker.add_task(event); } } } + worker.stop(); + return 0; }