我尝试用poco制作一个简单的tcp服务器。我使用Poco :: Net :: TCPServer类,这是一个多线程服务器,从技术上讲它是有效的。但有一件事是超级奇怪的。如果我启动服务器,获得一个或多个传入连接,我在3秒后获得100%的CPU使用率,但我无法弄清楚原因。
这是我的简单代码。
#include <iostream>
#include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerParams.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/Socket.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include <string>
using namespace std;
class newConnection: public Poco::Net::TCPServerConnection {
public:
newConnection(const Poco::Net::StreamSocket& s) :
Poco::Net::TCPServerConnection(s) {
}
void run() {
cout << "New connection from: " << socket().peerAddress().host().toString() << endl << flush;
const auto ct = Poco::Thread::current();
cout << "thread-id: " << ct->id() << endl;
bool isOpen = true;
Poco::Timespan timeOut(10,0);
unsigned char incommingBuffer[1000];
while(isOpen)
{
if (socket().poll(timeOut,Poco::Net::Socket::SELECT_READ) == false)
{
//cout << "TIMEOUT!" << endl << flush;
}
else
{
//cout << "RX EVENT!!! ---> " << endl << flush;
int nBytes = -1;
std::vector<char> bytes;
try
{
do// recive all bytes, if the buffer is to small for the whole data
{
nBytes = socket().receiveBytes(incommingBuffer, sizeof(incommingBuffer));
for(int i = 0; i < nBytes; i++)
{
bytes.push_back(incommingBuffer[i]);
}
}while(socket().available() > 0);
}
catch (Poco::Exception& exc)
{
//Handle your network errors.
cerr << "Network error: " << exc.displayText() << endl;
isOpen = false;
}
if (nBytes==0)
{
cout << "Client closes connection!" << endl << flush;
isOpen = false;
}
else
{
bytes.push_back('\0');
std::string line(&bytes[0]);
cout << line << endl;
const auto answer = std::string("you send me: ") + line;
socket().sendBytes(answer.c_str(),answer.size());
}
}
}
cout << "Connection finished!" << endl << flush;
}
};
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
class MyServer: public Poco::Util::ServerApplication
{
public:
MyServer(): _helpRequested(false)
{
}
~MyServer()
{
}
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
ServerApplication::initialize(self);
}
void uninitialize()
{
ServerApplication::uninitialize();
}
void defineOptions(OptionSet& options)
{
ServerApplication::defineOptions(options);
options.addOption(
Option("help", "h", "display help information on command line arguments")
.required(false)
.repeatable(false));
}
void handleOption(const std::string& name, const std::string& value)
{
ServerApplication::handleOption(name, value);
if (name == "help")
_helpRequested = true;
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("An echo server implemented using the Reactor and Acceptor patterns.");
helpFormatter.format(std::cout);
}
int main(const std::vector<std::string>& args)
{
if (_helpRequested)
{
displayHelp();
}
else
{
// get parameters from configuration file
const auto port = (unsigned short) config().getInt("MyServer.port", 1234);
//const int port = 1234;
Poco::Net::ServerSocket svs(port);
//Configure some server params.
Poco::Net::TCPServerParams* pParams = new Poco::Net::TCPServerParams();
pParams->setMaxThreads(4);
pParams->setMaxQueued(4);
pParams->setThreadIdleTime(100);
//Create your server
Poco::Net::TCPServer myServer(new Poco::Net::TCPServerConnectionFactoryImpl<newConnection>(), svs, pParams);
cout << "start server on " << svs.address().host().toString() << ":" << svs.address().port() << endl;
myServer.start();
waitForTerminationRequest();
}
return Application::EXIT_OK;
}
private:
bool _helpRequested;
};
int main(int argc, char** argv)
{
MyServer app;
return app.run(argc, argv);
}
python 3中的客户端代码
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 1234
BUFFER_SIZE = 1024
message = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
try:
message = input()
while message != "quit":
s.send(message.encode('utf-8'))
#data = s.recv(BUFFER_SIZE)
#print(data.decode('utf-8'))
message = input()
except BaseException:
pass
s.close()
有人知道为什么会这样吗?
我使用的是MacOS X和poco 1.7.5
问候 通卡
答案 0 :(得分:1)
我知道这是一个老问题,无论如何,我发现该问题与以下设置有关:pParams->setThreadIdleTime(100);
请注意,这是我对发生的情况的猜测:
void TCPServerDispatcher::run() {
...
int idleTime = (int) _pParams->getThreadIdleTime().totalMilliseconds(); `