副标题#e#
1 TCPServer 框架概述
POCO 库提供TCPServer框架,用以搭建自界说的 TCP 处事器。TCPServer维护一个毗连行列、一个毗连线程池。毗连线程用于处理惩罚毗连,毗连线程只要一空闲就不绝地从毗连行列中取毗连并举办处理惩罚。一旦毗连线程从毗连行列中取到一个毗连,就会建设一个TCPServerConnection毗连工具,而且挪用该工具的start()要领,直到start()要领返回,这个毗连工具就被删除了。
毗连线程的数量是动态的,其取决于毗连行列中列队的毗连数。虽然,你利用的时候可以设定毗连行列的最大容量,以防备在高并发应用的处事器上呈现毗连太多而使毗连行列溢出的悲剧产生。当毗连行列满了,却尚有新的毗连到来时,新来的毗连就会被当即悄无声息地封锁。
此刻我们总结一下,就是要有一个可运行的 TCP 处事应用措施(定名为PoechantTCPServer),尚有许多 TCP 毗连(定名为PoechantTCPConnection)。而这里我们用到工场模式(精确说是TCPServerConnectionFactory要我们用的),所以尚有一个 PoechantTCPConnectionFactory。
2 光说不做假把式
2.1 建设一个 PoechantTCPServer
或者你还不熟悉 POCO 中的 Application,不要紧,这不影响本文的论述。下面先建设一个 ServerApplication 如下:
// PoechantTCPServer.h #ifndef POECHANT_TCP_SERVER #define POECHANT_TCP_SERVER #include "Poco/Util/ServerApplication.h" #include "Poco/Util/Application.h" using Poco::Util::ServerApplication; using Poco::Util::Application; class PoechantTCPServer: public ServerApplication { public: PoechantTCPServer() {} ~PoechantTCPServer() {} protected: void initialize(Application& self); void uninitialize(); int main(const std::vector<std::string>& args) }; #endif
这样在挪用启动PoechantTCPServer时,会先挪用initialize,然后挪用main,在main竣事后会挪用uninitialize。其实现很简朴:
// PoechantTCPServer.cpp #include "PoechantTCPServer.h" void PoechantTCPServer::initialize(Application& self) { ServerApplication::loadConfiguration(); ServerApplication::initialize(self); } void PoechantTCPServer::uninitialize() { ServerApplication::uninitialize(); } int PoechantTCPServer::main(const std::vector<std::string>& args) { // 这个咱最后说 return Application::EXIT_OK; }
2.2 PoechantTCPConnection
毗连类的界说很简朴,结构函数要传入一个 StreamSocket 和其他你需要的参数。
// PoechantTCPConnection.h #ifndef POECHANT_TCP_CONNECTION_H #define POECHANT_TCP_CONNECTION_H #include "Poco/Net/TCPServerConnection.h" #include "Poco/Net/StreamSocket.h" #include <string> class PoechantTCPConnection: public TCPServerConnection { public: PoechantTCPConnection(const StreamSocket& s, const std::string& arg1, int arg2, double arg3); void run(); private: std::string _arg1; int _arg2; double _arg3; }; #endif
实现如下:
// PoechantTCPConnection.cpp #include "PoechantTCPConnection.h" #include "Poco/Util/Application" #include "Poco/Timestamp.h" #include "Poco/Exception.h" #include "Poco/DateTimeFormatter.h" PoechantTCPConnection(const StreamSocket& s, const std::string& arg1, int arg2, double arg3): TCPServerConnection(s), _arg1(arg1), _arg2(arg2), _arg3(arg3) { } void run() { Application& app = Application::instance(); // 日志输出毗连的TCP用户的地点(IP和端口) app.logger().information("Request from " + this->socket().peerAddress().toString()); try { // 向客户端发送数据,这里以发送一个暗示时间的字符串为例 Timestamp now; std::string dt(DateTimeFormatter::format(now, _format)); dt.append("\r\n"); socket().sendBytes(dt.data(), (int) dt.length()); } catch (Poco::Exception& e) { app.logger().log(e); } }
2.3 PoechantTCPConnectionFactory
工场模式不必多说,名字唬人,其实很是很是简朴(精确的说设计模式大部门名字都唬人,但大部门都很有用,设计模式自己并不牛B,能把设计模式抽象提炼出来成我们此刻认为很简朴的这些模式的那几小我私家很牛B)。详细如下:
// PoechantTCPConnectionFactory.h #ifndef POECHANT_TCP_CONNECTION_FACTORY_H #define POECHANT_TCP_CONNECTION_FACTORY_H #include "Poco/Net/TCPServerConnectionFactory.h" #include "Poco/Net/TCPServerConnection.h" #include "Poco/Net/StreamSocket.h" #include <string> class PoechantTCPConnectionFactory: public TCPServerConnectionFactory { public: PoechantTCPConnectionFactory(const std::string arg1, int arg2, double arg3) : _arg1(arg1), _arg2(arg2), _arg3(arg3) { } TCPServerConnection* createConnection(const StreamSocket& socket) { return new PoechantTCPConnection(socket, arg1, arg2, arg3); } private: std::string arg1; int arg2; double arg3; }; #endif
#p#副标题#e#
2.4 启动
#p#分页标题#e#
转头来说PoechantTCPServer::main(const std::vector<std::string>& args),其进程就是建设一个绑定了地点的ServerSocket,把它传给TCPServer,虽然别忘了把工程工具也给你的TCPServer传一个。最后就start(),waitForTerminationRequest和stop()就行了。
int PoechantTCPServer::main(const std::vector<std::string>& args) { unsigned short port = (unsigned short) config().getInt("PoechantTCPServer.port", 12346); std::string format(config().getString("PoechantTCPServer.format", DateTimeFormat::ISO8601_FORMAT)); // 1. Bind a ServerSocket with an address ServerSocket serverSocket(port); // 2. Pass the ServerSocket to a TCPServer TCPServer server(new PoechantTCPConnectionFactory(format), serverSocket); // 3. Start the TCPServer server.start(); // 4. Wait for termination waitForTerminationRequest(); // 5. Stop the TCPServer server.stop(); return Application::EXIT_OK; }
然后写一个措施进口:
#include "PoechantTCPServer.h" int main(int argc, char **argv) { return PoechantTCPServer().run(argc, argv); }
3 写一个 Client 测测
TCPServer 要用 TCP 的客户端来测试。在 POCO 中有富厚的 Socket,个中 TCP 方法的 Socket 有:
Poco::Net::ServerSocket
Poco::Net::StreamSocket
Poco::Net::DialogSocket
Poco::Net::SecureServerSocket
Poco::Net::SecureStreamSocket
UDP 方法的 Socket 有:
Poco::Net::DatagramSocket
Poco::Net::MulticastSocket
一个 TCP 方法 Client 如下(这里用了 while 轮回,其实可以在收到数据后就封锁的)
#include <iostream> #include "Poco/Net/StreamSocket.h" #include "Poco/Net/SocketAddress.h" #define BUFFER_SIZE 1024 using Poco::Net::SocketAddress; using Poco::Net::StreamSocket; int main (int argc, const char * argv[]) { SocketAddress address("127.0.0.1", 12346); StreamSocket socket(address); char buffer[BUFFER_SIZE]; while (true) { if (socket.available()) { int len = socket.receiveBytes(buffer, BUFFER_SIZE); buffer[len] = '\0'; std::cout << "" << buffer << std::endl; } } return 0; }
来自柳大的CSDN博客:Blog.CSDN.net/Poechant
查察全套文章:http://www.bianceng.cn/Programming/cplus/201301/35022.htm