使用poco库,实现tcp server例子

代码:

//
// UserTcpServer.cpp
//
// This sample demonstrates the SocketReactor and SocketAcceptor classes.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:    BSL-1.0
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>

#include <iostream>

#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/SocketAcceptor.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/NObserver.h"
#include "Poco/Exception.h"
#include "Poco/Thread.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/Delegate.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"

#include "Poco/LocalDateTime.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeParser.h"


class UserServiceHandler
{
public:
    UserServiceHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor):
        socket_(socket), reactor_(reactor)
    {
        Poco::Util::Application& app = Poco::Util::Application::instance();
        app.logger().information("Connection from " + socket.peerAddress().toString());

        recv_buf_ = (uint8_t *)malloc(BUFFER_SIZE);
        send_buf_ = (uint8_t *)malloc(BUFFER_SIZE);

        recv_len_ = 0;
        send_len_ = 0;

        reactor_.addEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::ReadableNotification>(*this, &UserServiceHandler::onSocketReadable));
        reactor_.addEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::ShutdownNotification>(*this, &UserServiceHandler::onSocketShutdown));

    }
    
    ~UserServiceHandler()
    {
        Poco::Util::Application& app = Poco::Util::Application::instance();
        try
        {
            app.logger().information("Disconnecting " + socket_.peerAddress().toString());
        }
        catch (...)
        {
        }
        reactor_.removeEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::ReadableNotification>(*this, &UserServiceHandler::onSocketReadable));
        reactor_.removeEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::WritableNotification>(*this, &UserServiceHandler::onSocketWritable));
        reactor_.removeEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::ShutdownNotification>(*this, &UserServiceHandler::onSocketShutdown));

        if (recv_buf_)
        {
            free(recv_buf_);
            recv_buf_ = NULL;
        }
        if (send_buf_)
        {
            free(send_buf_);
            send_buf_ = NULL;
        }
    }


    void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf)
    {
        recv_len_ = socket_.receiveBytes(recv_buf_, BUFFER_SIZE);
        if (recv_len_ > 0)
        {
            // do some user work here
            // do some user work here
            // do some user work here
            // sleep(1); // 不要sleep,不要花时间处理数据,先把数据拷贝到链表里,放其他线程单独处理数据。
            
            // example
            // receive string
            // return server date
            printf("RECV - %s\n\r", recv_buf_);

            Poco::LocalDateTime now;
            std::string time_str =  Poco::DateTimeFormatter::format(now, Poco::DateTimeFormat::ISO8601_FRAC_FORMAT);
            
            //
            send_len_ = sprintf((char *)send_buf_, "%s, SVR - %s\n\r", recv_buf_, time_str.c_str());
            send_buf_[send_len_ ++] = '\0';

            // en send
            reactor_.addEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::WritableNotification>(*this, &UserServiceHandler::onSocketWritable));
        }
    }
    
    void onSocketWritable(const Poco::AutoPtr<Poco::Net::WritableNotification>& pNf)
    {
        if (send_len_ > 0)
        {
            socket_.sendBytes(send_buf_, send_len_);

        }
        //
        reactor_.removeEventHandler(socket_, Poco::NObserver<UserServiceHandler, Poco::Net::WritableNotification>(*this, &UserServiceHandler::onSocketWritable));
    }

    void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf)
    {
        delete this;
    }
    
private:
    enum
    {
        BUFFER_SIZE = 1024
    };
    
    Poco::Net::StreamSocket   socket_;
    Poco::Net::SocketReactor& reactor_;

    uint8_t    *recv_buf_;        // 接收缓存区
    uint8_t    *send_buf_;        // 发送缓存区

    int    recv_len_;
    int send_len_;
};

class UserTcpServer: public Poco::Util::ServerApplication
{
public:
    UserTcpServer(Poco::Net::SocketAddress &socket_addr)
    {
        socket_addr_ = &socket_addr;
    }
    
    ~UserTcpServer()
    {
    }

protected:
    void initialize(Application& self)
    {
        Poco::Util::ServerApplication::initialize(self);
    }
        
    void uninitialize()
    {
        Poco::Util::ServerApplication::uninitialize();
    }

    int main(const std::vector<std::string>& args)
    {
        // set-up a server socket
        Poco::Net::ServerSocket svs(*socket_addr_);
        // set-up a SocketReactor...
        Poco::Net::SocketReactor reactor;
        // ... and a SocketAcceptor
        Poco::Net::SocketAcceptor<UserServiceHandler> acceptor(svs, reactor);
        // run the reactor in its own thread so that we can wait for 
        // a termination request
        Poco::Thread thread;
        thread.start(reactor);
        // wait for CTRL-C or kill
        Poco::Util::ServerApplication::waitForTerminationRequest();
        // Stop the SocketReactor
        reactor.stop();
        thread.join();

        return Poco::Util::Application::EXIT_OK;
    }
    
private:
    Poco::Net::SocketAddress *socket_addr_;
};

int main(int argc, char** argv)
{
    int server_port = 8089;
    std::string server_ip("localhost");
    Poco::Net::SocketAddress socket_addr(server_ip.c_str(), server_port);


    UserTcpServer app(socket_addr);
    return app.run(argc, argv);
}

makefile:

export TOP_DIR = $(PWD)

# 包含参数配置文件
#include ./Makefile.param

# 目标文件名称、编译后文件位置
PWD := $(shell pwd)
INSTALLDIR = .

TARGET = tcp_server_test
DBGTARGET = $(INSTALLDIR)/$(TARGET)d
RLSTARGET = $(INSTALLDIR)/$(TARGET)

# 配置编译器
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
LD_CXX = $(CROSS_COMPILE)g++
STRIP = $(CROSS_COMPILE)strip
RM = rm



# 配置依赖头文件、库文件路径
INCPATH += -I. -I$(REL_INC) -I/usr/local/include 
LIBPATH += -L. -L$(REL_LIB) -L/usr/local/lib 

# 配置编译参数
FLAGS_C += $(MACRO_DEFINE) $(INCPATH) $(CFLAGS) -Wall 
FLAGS_CXX += $(MACRO_DEFINE) $(INCPATH) $(CFLAGS) -Wall 
LDFLAGS += $(CFLAGS) $(LIBPATH) $(LIBS_CFLAGS) -pie -fPIE 
LIBS += -lPocoFoundation -lPocoUtil -lPocoNet -lpthread -lm -lc -lgcc -lgcc_s -ldl 

DBG_FLAGS = -g -D__DEBUG
RLS_FLAGS = -O2 -fno-strict-aliasing


# 源文件包含
SRCS_C  = $(wildcard *.c)
SRCS_CXX  = $(wildcard *.cpp)
SRCS_H  = $(wildcard *.h*)


# obj文件包含
OBJ_DBG_DIR = 0-obj/$(CROSS_COMPILE)dbg
OBJ_RLS_DIR = 0-obj/$(CROSS_COMPILE)rls

OBJS_C_DBG = $(addprefix $(OBJ_DBG_DIR)/,$(SRCS_C:%.c=%.o))
OBJS_CXX_DBG = $(addprefix $(OBJ_DBG_DIR)/,$(SRCS_CXX:%.cpp=%.o))
OBJS_C_RLS = $(addprefix $(OBJ_RLS_DIR)/,$(SRCS_C:%.c=%.o))
OBJS_CXX_RLS = $(addprefix $(OBJ_RLS_DIR)/,$(SRCS_CXX:%.cpp=%.o))

# 编译动作
COMPILE_C = $(CC) $(FLAGS_C) -c
COMPILE_CXX = $(CXX) $(FLAGS_CXX) -c
LINK_CXX = $(LD_CXX) $(LDFLAGS) 



.PHONY: clean debug release install

all:	release

install:
	install -d $(EXEC_DIR)
	install $(RLSTARGET) $(EXEC_DIR)
	install -m 444 $(TARGET).txt $(EXEC_DIR)

release: $(RLSTARGET)
	$(STRIP) $(RLSTARGET)

debug: $(DBGTARGET)
	@echo $(TARGET)_debug_done

$(RLSTARGET):	$(OBJS_C_RLS) $(OBJS_CXX_RLS)
	@mkdir -p $(INSTALLDIR)
	$(LINK_CXX) -o $@ $^ $(LIBS) 

$(DBGTARGET):	$(OBJS_C_DBG) $(OBJS_CXX_DBG)
	@mkdir -p $(INSTALLDIR)
	$(LINK_CXX) -o $@ $^ $(LIBS) 


$(OBJS_CXX_RLS):	$(OBJ_RLS_DIR)/%.o: %.cpp $(SRCS_H)
	@mkdir -p $(OBJ_RLS_DIR)
	$(COMPILE_CXX) $(RLS_FLAGS) -o $@ $<
	
$(OBJS_C_RLS):		$(OBJ_RLS_DIR)/%.o: %.c $(SRCS_H)
	@mkdir -p $(OBJ_RLS_DIR)
	$(COMPILE_C) $(RLS_FLAGS) -o $@ $<	

$(OBJS_CXX_DBG):	$(OBJ_DBG_DIR)/%.o: %.cpp $(SRCS_H)
	@mkdir -p $(OBJ_DBG_DIR)
	$(COMPILE_CXX) $(DBG_FLAGS) -o $@ $<

$(OBJS_C_DBG):		$(OBJ_DBG_DIR)/%.o: %.c $(SRCS_H)
	@mkdir -p $(OBJ_DBG_DIR)
	$(COMPILE_C) $(DBG_FLAGS) -o $@ $<

clean:
	-$(RM) -rf  *~ *.d .dep 0-obj
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值