2013-07-25 23 views
1

我正在爲Linux上的套接字編寫一個C++封裝器。 我可以連接讀取/寫入到HTTP服務器我的民意調查功能完美的閱讀,但由於某種原因,它不會與寫作工作。我一直在使用gdb的嘗試,它似乎民調設置fd.revents爲0時fd.events爲POLLOUTC++套接字永遠不會寫輪詢

投票代碼:

/** 
*@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; 
} 

您在兩個POLLOUTdefault箱子缺少一個break:當輪詢寫

+0

if(request.reply == mizaru :: POLL_REPLY_READ){ std :: cout <<「fail test_poll first read」<< std :: endl; return false;}當應答==讀取時,是否應該顯示失敗消息? – Lochemage

+0

@Lochemage是第一個HTTP服務器還沒有收到回覆請求,因此沒有數據要讀取,如果我從測試用例中刪除輪詢寫入測試,它會成功 –

回答

5

translate_request()測試失敗。 POLLOUT落入default,擦除POLLOUT發生的證據。

+0

謝謝!我不知道我是如何錯過的 –