happy-ip開發tcp server樣例
主函式程式碼如下
#include <ip/server/tcp_server.h> #include "server_message_factory.h" using namespace klicen::asio::ip;
int main() { // 預設建立執行緒池的大小為4。 //IoServicePool::singleton::Create(4); uint16_t port = 1234; TcpServer tcp_server(port); printf("tcp server is run (port=%d)\n", port); tcp_server.SetMessageFactory(make_shared <ServerMessageFactory>()); IoServicePool::singleton::GetInstance()->Run();
return EXIT_SUCCESS; }
主函式中只需要例項化TcpServer類(TcpServer類建構函式提供引數read_work_threads,設定投遞給業務層處理讀取資料的執行緒池大小),設定TcpServer類的MessageFactory。IoServicePool如果沒有呼叫create函式, 預設建立執行緒池的大小為4。一定記得在最後呼叫IoServicePool類的run函式,啟動io執行緒池。
server_message_factory.h程式碼如下
#pragma once #include <ip/message_factory.h> #include <utils.h>
class ServerMessageFactory : public klicen::asio::ip::MessageFactory { using klicen::asio::ip::MessageFactory::MessageFactory; CREATE(ServerMessageFactory); private: virtual bool IsConsumedForRead(const uint8_t* buffer, const size_t& length, size_t& deal_length, bool& has_package) override final; virtual bool HandleRead(const uint8_t* buffer, const size_t& length, string& response) override final; };
需要實現IsConsumedForRead和HandleRead兩個虛擬函式。IsConsumedForRead函式是判斷資料包是否接受完成,HandleRead表示收到完整資料包返回個使用者層處理(可在TcpServer類建構函式設定引數read_work_threads,構造獨立的執行緒池來供業務層處理網路層讀取到的資料,防止阻塞網路層的讀事件)。
server_message_factory.cpp程式碼如下
#include "server_message_factory.h" #include <boost/asio.hpp>
bool ServerMessageFactory::IsConsumedForRead(const uint8_t* buffer, const size_t& length, size_t& deal_length, bool& has_package) { uint32_t content_length = 0; if (length < 4 || (content_length = boost::asio::detail::socket_ops::network_to_host_long(*reinterpret_cast <const uint32_t *>(buffer))) > length - 4) { has_package = true;
return false; } deal_length = 4 + content_length;
return true; }
bool ServerMessageFactory::HandleRead(const uint8_t* buffer, const size_t& length, string& response) { printf("receive client data: %s\n", ToHost(buffer, length).content.c_str()); response = ToNetwork("server response data");
return true; }
設定has_package標識的同時返回false,代表資料不是一個完整的包,還有後續資料包。返回true的時候,記得設定deal_length引數哦。
執行結果如下
tcp server is run (port=1234) receive client data: 33333333333 receive client data: 33333333333 receive client data: 1111111111111 表示繫結埠為1234,收到客戶端3條資訊receive client data後面就是具體的客戶端傳送的資料內容。是不是很簡單,,歡迎大家使用。
boost庫1.63版本標頭檔案與庫檔案下載路徑
windows編譯引數
cmake .. -LA -DBOOST_INCLUDE_DIR='E:\git\boost\include' -DBOOST_LIB_DIR='E:\git\boost\lib\win32_debug' -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS_DEBUG="/MTd /Zi /Ob0 /Od /RTC1" -DBUILD_EXAMPLES=ON
linux編譯引數
cmake .. -LA -DBOOST_INCLUDE_DIR='/mnt/e/git/boost/include' -DBOOST_LIB_DIR='/mnt/e/git/boost/lib/linux_debug' -DCMAKE_BUILD_TYPE=Debug -DBUILD_EXAMPLES=ON