我正在嘗試使用boost單元測試來測試我的boost asio套接字偵聽器。監聽器的目的是簡單地監聽一個端口並讀取所有內容並將其保存到一個隊列中併發回一個http響應頭。即使長時間等待,C++線程也不會加入
作爲第一步,我創建了一個客戶端向偵聽器發送消息並讀取來自偵聽器的響應消息。我還創建了一個線程來啓動偵聽器。主線程將發送和接收來自Listener的消息。我可以在客戶端和列表程序之間發送和接收消息。但是當我嘗試加入時,它並沒有加入並繼續等待加入(我猜)。
請幫助我出了什麼問題。
在此先感謝。
Listener.hpp
#ifndef Listener_hpp
#define Listener_hpp
#include <iostream>
#include <stdio.h>
#include <atomic>
#include <boost/asio.hpp>
#include "sharedQueue.hpp"
using namespace std;
using namespace boost;
using boost::asio::ip::tcp;
class Listener{
private:
int port;
std::atomic<bool> m_stop;
boost::system::error_code error;
boost::asio::io_service io_service;
std::shared_ptr<sharedQueue> queue_ptr;
void saveMessageToQueue(std::string,std::string);
Listener(int portToListen, std::shared_ptr<sharedQueue> queue_unique_ptr);
Listener(const Listener&);
Listener& operator=(const Listener&);
public:
static Listener& getInstance(int portToListenOn, std::shared_ptr<sharedQueue> queue_unique_ptr);
void listen();
};
#endif /* Listener_hpp */
Listener.cpp
#include "Listener.hpp"
Listener::Listener(int portToListen, std::shared_ptr<sharedQueue> queue_unique_ptr):port(portToListen), queue_ptr(queue_unique_ptr),m_stop(false)
{;}
Listener& Listener::getInstance(int portToListenOn, std::shared_ptr<sharedQueue> queue_unique_ptr)
{
static Listener instance(portToListenOn, queue_unique_ptr);
return instance;
}
void Listener::stopListen(){
m_stop = true;
}
void Listener::listen()
{
try{
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));
while(!m_stop)
{
std::cout<<"Server is listening on port "<<port<<std::endl;
boost::asio::ip::tcp::socket socket(io_service);
acceptor.accept(socket);
std::cout<<"Connection Request Accepted "<<std::endl;
std::array<char, 512> buf;
socket.read_some(boost::asio::buffer(buf), error);
std::string responseBack =" HTTP:300";
boost::asio::write(socket, boost::asio::buffer(responseBack, responseBack.size()), error);
}
}
catch (std::exception& e)
{
std::cerr <<"Listener Exception : "<< e.what() << std::endl;
exit(0);
}
}
sharedQueue.hpp
#ifndef SharedQueue_hpp
#define SharedQueue_hpp
#include <stdio.h>
#include <iostream>
class sharedQueue{
public:
sharedQueue(){};
void pushToQueue(std::string str){};
};
#endif /* SharedQueue_hpp */
ClientTestHelper.hpp
#ifndef ClientTestHelper_hpp
#define ClientTestHelper_hpp
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
class ClientTestHelper
{
string address = "";
public:
ClientTestHelper(std::string addressToPush){
this->address = addressToPush;
};
~ClientTestHelper(){};
std::string sendMessage(string message);
};
#endif /* ClientTestHelper_hpp */
ClientTestHelper.cpp
#include "ClientTestHelper.hpp"
std::string ClientTestHelper::sendMessage(string message){
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(address, boost::asio::ip::resolver_query_base::numeric_service);
boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
boost::asio::streambuf writeBuffer;
boost::asio::streambuf readBuffer;
std::string str = message;
boost::system::error_code error;
boost::asio::write(socket, boost::asio::buffer(str, str.size()), error);
std::array<char,1024> buf;
socket.read_some(boost::asio::buffer(buf), error);
std::string respo = buf.data();
cout<<respo<<std::endl;
return respo;
}
ListenerTest.hpp
#ifndef ListenerTest_hpp
#define ListenerTest_hpp
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <iostream>
#include <stdio.h>
#include <thread>
#include <boost/test/unit_test.hpp>
#include "Listener.hpp"
#include "ClientTestHelper.hpp"
#include "SharedQueue.hpp"
struct ListenerTestFixture{
public:
void startListen(Listener &receiver){
receiver.listen();
}
std::shared_ptr<sharedQueue> myQueue = std::make_shared<sharedQueue>();
Listener &receiver = Listener::getInstance(8282, myQueue);
void doRun(){
receiver.listen();
}
ClientTestHelper *client = new ClientTestHelper("8282");
ListenerTestFixture(){};
~ListenerTestFixture(){};
};
#endif /* ListenerTest_hpp */
ListenerTest.cpp
#include "ListenerTest.hpp"
BOOST_FIXTURE_TEST_CASE(connectionTest, ListenerTestFixture)
{
std::thread t1(&ListenerTestFixture::doRun, *this);
std::string response = "";
response = client->sendMessage("SomeRandom Messages \r\n\r\n\r\n");
//receiver.~Listener();
receiver.stopListen();
std::cout<<"Response Received "<<response;
t1.join();
std::cout<<"Finished Testing "<<endl;
}
控制檯輸出對於澄清:
Running 1 test case...
Server is listening on port 8585
Connection Request Accepted
Server is listening on port 8585
HTTP:300
在這個執行沒有停止之後等待加入。
編輯:修改後的監聽器類添加成員m_stop和stopListen(),更改爲(;;)成while(!m_stop)。包含頭文件。
爲什麼你手動調用一個對象的析構函數? – Blacktempel
爲了加入,線程函數必須退出。 「聽」會退出嗎? –
請提供示例代碼SSCCE。由於錯誤 – sehe