我正在爲Linux上的套接字編寫一個C++封裝器。 我可以連接讀取/寫入到HTTP服務器我的民意調查功能完美的閱讀,但由於某種原因,它不會與寫作工作。我一直在使用gdb的嘗試,它似乎民調設置fd.revents
爲0時fd.events爲POLLOUT
C++套接字永遠不會寫輪詢
投票代碼:
/**
*@brief assigns request.reply based on fd.revents
*/
static void translate_request(mizaru::PollRequest &request, pollfd &fd)
{
assert((fd.revents & POLLHUP) == 0);
assert((fd.revents & POLLERR) == 0);
assert((fd.revents & POLLNVAL) == 0);
switch(fd.revents)
{
case (POLLIN | POLLOUT) :
request.reply = mizaru::POLL_REPLY_RW;
break;
case POLLIN :
request.reply = mizaru::POLL_REPLY_READ;
break;
case POLLOUT :
request.reply = mizaru::POLL_REPLY_WRITE;
default :
request.reply = 0;
}
}
/**
* @fills in fd.events based on request.request
* and fd.fd based on request.sock
*/
static void prep_request(mizaru::PollRequest &request, pollfd &fd)
{
fd.fd = request.sock.get_handle();
switch(request.request)
{
case mizaru::PollType::POLL_READ :
fd.events = POLLIN;
break;
case mizaru::PollType::POLL_WRITE :
fd.events = POLLOUT;
break;
default :
fd.events = POLLIN | POLLOUT;
}
}
void mizaru::trans::poll(mizaru::PollRequest &request,const std::chrono::milliseconds& wait_time) noexcept
{
pollfd fd;
prep_request(request, fd);
poll(&fd, 1, wait_time.count());
translate_request(request, fd);
}
mizaru::PollRequest
結構:
struct PollRequest
{
PollRequest(PollType request, const SyncSocket &sock) : sock(sock), request(request), reply(POLL_REPLY_FAIL) {}
const SyncSocket & sock;
PollType request;
uint8_t reply;
};
SyncSocket.get_handle()
剛剛返回由FD返回socket(int,int,int)
in sys/socket.h
測試功能:
bool test_poll()
{
mizaru::IPv4 ip ("54.225.138.124");
mizaru::SyncSocketTCP sock (ip, 80 ,true);
mizaru::PollRequest request{mizaru::PollType::POLL_READ, sock};
std::chrono::milliseconds time(1000);
mizaru::poll(request, time);
if(request.reply == mizaru::POLL_REPLY_READ)
{
std::cout << "fail test_poll first read" <<std::endl;
return false;
}
request.request = mizaru::PollType::POLL_WRITE;
mizaru::poll(request, time);
if(request.reply != mizaru::POLL_REPLY_WRITE)
{
std::cout << "fail test_poll first write" << std::endl;
return false;
}
std::string toWrite ("GET/http/1.1\nHost: httpbin.org\n\n");
mizaru::byte_buffer write_buff;
for (char c : toWrite)
{
write_buff.push_back (c);
}
unsigned int r_value = sock.write (write_buff);
if (r_value != toWrite.size())
{
std::cout << "fail test_poll r_value" << std::endl;
return false;
}
request.request = mizaru::PollType::POLL_READ;
mizaru::poll(request, time);
if(request.reply != mizaru::POLL_REPLY_READ)
{
std::cout << "fail test_poll second read" << std::endl;
return false;
}
request.request = mizaru::PollType::POLL_WRITE;
mizaru::poll(request, time);
if(request.reply != mizaru::POLL_REPLY_WRITE)
{
std::cout << "fail test_poll second write " << std::endl;
return false;
}
return true;
}
PollType
枚舉:
enum PollType {POLL_READ, POLL_WRITE, POLL_RW};
POLL_REPLY_*
常數:
constexpr uint8_t POLL_REPLY_READ = 0x01;
constexpr uint8_t POLL_REPLY_WRITE = 0x02;
constexpr uint8_t POLL_REPLY_RW = POLL_REPLY_READ | POLL_REPLY_WRITE;
constexpr uint8_t POLL_REPLY_FAIL = 0;
我很抱歉,示例代碼是不能直接編譯,我試圖讓它短, 由於我得到了正確的HTTP 200 OK回覆,你可以假設連接和讀/寫都是句柄d正確。
switch(fd.revents)
{
case (POLLIN | POLLOUT) :
request.reply = mizaru::POLL_REPLY_RW;
break;
case POLLIN :
request.reply = mizaru::POLL_REPLY_READ;
break;
case POLLOUT :
request.reply = mizaru::POLL_REPLY_WRITE;
default :
request.reply = 0;
}
您在兩個POLLOUT
和default
箱子缺少一個break
:當輪詢寫
if(request.reply == mizaru :: POLL_REPLY_READ){ std :: cout <<「fail test_poll first read」<< std :: endl; return false;}當應答==讀取時,是否應該顯示失敗消息? – Lochemage
@Lochemage是第一個HTTP服務器還沒有收到回覆請求,因此沒有數據要讀取,如果我從測試用例中刪除輪詢寫入測試,它會成功 –