C++套接字从未准备好使用轮询进行写入
C++ socket never ready for write with poll
我正在为Linux上的套接字编写一个C++包装器。我可以将读/写连接到http服务器,我的轮询功能非常适合阅读,但由于某些原因,它不适合写作。我尝试过使用gdb,当fd.events是POLLOUT
时,轮询似乎将fd.revents
设置为0
轮询代码:
/**
*@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()
只是返回socket(int,int,int)
在sys/socket.h
中返回的fd
测试功能:
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.1nHost: httpbin.orgnn" );
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;
很抱歉,示例代码无法直接编译,我试图将其缩短,由于我得到了一个正确的HTTP200OK回复,您可以假设连接和读/写处理得当。轮询写入时测试失败
在translate_request()
:中
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
。POLLOUT
下降到default
,消除了POLLOUT
发生的证据。
相关文章:
- C++套接字客户端到 Python 服务器未创建连接
- 接受套接字,但m_socket.远程终结点引发 传输终结点未连接
- C++ 套接字 - 发送 - 未收到数据
- 套接字记录未读取任何消息
- 如何确定网络堆栈何时准备好再次打开到同一主机/端口的套接字?
- Datagram套接字服务器未从客户端接收消息
- RAW ICMP 套接字:recvfrom() 未接收任何数据
- 用于枚举绑定但未连接的套接字的 API
- Qt Creator未定义套接字-Linux
- 在Wireshark中看到的数据报,未由QT UDP套接字收到
- 服务重新启动后未释放套接字
- Qt套接字未等待写入字节
- Boost Asio未完成对套接字的写入
- 套接字:我的select()函数逻辑有未定义的行为
- 为什么套接字未正确处理此缓冲区大小
- 原始套接字未拾取 ARP 请求
- C++套接字从未准备好使用轮询进行写入
- 套接字未接收到完整的流
- 套接字未创建win32 c++
- 套接字未接收有关 HPUX 的完整数据