barrier/net/CTCPListenSocket.cpp

77 lines
1.5 KiB
C++
Raw Normal View History

2001-10-06 14:13:28 +00:00
#include "CTCPListenSocket.h"
#include "CTCPSocket.h"
#include "CNetworkAddress.h"
#include "XIO.h"
#include "XSocket.h"
2001-10-06 14:13:28 +00:00
#include "CThread.h"
//
// CTCPListenSocket
//
CTCPListenSocket::CTCPListenSocket()
{
m_fd = CNetwork::socket(PF_INET, SOCK_STREAM, 0);
if (m_fd == CNetwork::Null) {
2001-10-06 14:13:28 +00:00
throw XSocketCreate();
}
}
CTCPListenSocket::~CTCPListenSocket()
{
try {
close();
}
catch (...) {
// ignore
}
}
void
2002-06-17 13:31:21 +00:00
CTCPListenSocket::bind(const CNetworkAddress& addr)
2001-10-06 14:13:28 +00:00
{
if (CNetwork::bind(m_fd, addr.getAddress(),
addr.getAddressLength()) == CNetwork::Error) {
if (CNetwork::getsockerror() == CNetwork::kEADDRINUSE) {
2001-10-06 14:13:28 +00:00
throw XSocketAddressInUse();
}
throw XSocketBind();
}
if (CNetwork::listen(m_fd, 3) == CNetwork::Error) {
2001-10-06 14:13:28 +00:00
throw XSocketBind();
}
}
IDataSocket*
CTCPListenSocket::accept()
2001-10-06 14:13:28 +00:00
{
// accept asynchronously so we can check for cancellation
CNetwork::PollEntry pfds[1];
pfds[0].fd = m_fd;
pfds[0].events = CNetwork::kPOLLIN;
2001-10-06 14:13:28 +00:00
for (;;) {
CThread::testCancel();
2002-06-02 23:07:57 +00:00
const int status = CNetwork::poll(pfds, 1, 10);
if (status > 0 && (pfds[0].revents & CNetwork::kPOLLIN) != 0) {
CNetwork::Address addr;
CNetwork::AddressLength addrlen = sizeof(addr);
CNetwork::Socket fd = CNetwork::accept(m_fd, &addr, &addrlen);
if (fd != CNetwork::Null) {
return new CTCPSocket(fd);
}
2001-10-06 14:13:28 +00:00
}
}
}
void
CTCPListenSocket::close()
2001-10-06 14:13:28 +00:00
{
if (m_fd == CNetwork::Null) {
2001-10-06 14:13:28 +00:00
throw XIOClosed();
}
if (CNetwork::close(m_fd) == CNetwork::Error) {
2001-10-06 14:13:28 +00:00
throw XIOClose();
}
m_fd = CNetwork::Null;
2001-10-06 14:13:28 +00:00
}