recovering from a closed TCP connection

pull/3/head
Tom Early 2 years ago
parent a726c9ee22
commit ee1bd2228b

@ -44,12 +44,22 @@ void CTCSocket::Close(char mod)
std::cerr << "Could not find module '" << mod << "'" << std::endl; std::cerr << "Could not find module '" << mod << "'" << std::endl;
return; return;
} }
if (m_Pfd[pos].fd < 0)
{
std::cerr << "Close(" << mod << ") is already closed" << std::endl;
return;
}
Close(m_Pfd[pos].fd); Close(m_Pfd[pos].fd);
m_Pfd[pos].fd = -1; m_Pfd[pos].fd = -1;
} }
void CTCSocket::Close(int fd) void CTCSocket::Close(int fd)
{ {
if (fd < 0)
{
std::cerr << "Close(fd) : fd is -1" << std::endl;
return;
}
for (auto &p : m_Pfd) for (auto &p : m_Pfd)
{ {
if (fd == p.fd) if (fd == p.fd)
@ -140,7 +150,6 @@ bool CTCSocket::receive(int fd, STCPacket *packet)
if (0 == n) if (0 == n)
{ {
std::cerr << "recv(): Module '" << GetMod(fd) << "' has been closed from the other side" << std::endl; std::cerr << "recv(): Module '" << GetMod(fd) << "' has been closed from the other side" << std::endl;
Close(fd);
return true; return true;
} }
@ -180,18 +189,25 @@ bool CTCServer::Receive(char module, STCPacket *packet, int ms)
if (pfds->revents & POLLIN) if (pfds->revents & POLLIN)
{ {
rv = ! receive(pfds->fd, packet); rv = receive(pfds->fd, packet);
} }
// I think it's possible that even if we read the data, the socket can have an error after the read... // It's possible that even if we read the data, the socket can have an error after the read...
// So we'll check... // So we'll check...
if (pfds->revents & POLLERR || pfds->revents & POLLHUP) if (pfds->revents & POLLERR || pfds->revents & POLLHUP)
{ {
std::cerr << ((pfds->revents & POLLERR) ? "POLLERR" : "POLLHUP") << " received on module " << module << "', closing socket" << std::endl; if (pfds->revents & POLLERR)
std::cerr << "POLLERR received on module '" << module << "', closing socket" << std::endl;
if (pfds->revents & POLLHUP)
std::cerr << "POLLHUP received on module '" << module << "', closing socket" << std::endl;
Close(pfds->fd); Close(pfds->fd);
} }
if (pfds->revents & POLLNVAL)
{
std::cerr << "POLLNVAL received on module " << module << "'" << std::endl;
}
return rv; return ! rv;
} }
bool CTCServer::Open(const std::string &address, const std::string &modules, uint16_t port) bool CTCServer::Open(const std::string &address, const std::string &modules, uint16_t port)
@ -406,8 +422,7 @@ bool CTCClient::ReConnect()
return rv; return rv;
} }
// returns true if there's an error, but there still make be something in the returned queue void CTCClient::Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms)
bool CTCClient::Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms)
{ {
for (auto &pfd : m_Pfd) for (auto &pfd : m_Pfd)
pfd.revents = 0; pfd.revents = 0;
@ -417,13 +432,12 @@ bool CTCClient::Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms)
if (rv < 0) if (rv < 0)
{ {
perror("Receive poll"); perror("Receive poll");
return true; return;
} }
if (0 == rv) if (0 == rv)
return false; return;
bool some_closed = false;
for (auto &pfd : m_Pfd) for (auto &pfd : m_Pfd)
{ {
if (pfd.fd < 0) if (pfd.fd < 0)
@ -447,8 +461,11 @@ bool CTCClient::Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms)
{ {
std::cerr << "IO ERROR on Receive module " << GetMod(pfd.fd) << std::endl; std::cerr << "IO ERROR on Receive module " << GetMod(pfd.fd) << std::endl;
Close(pfd.fd); Close(pfd.fd);
some_closed = true; }
if (pfd.revents & POLLNVAL)
{
std::cerr << "POLLNVAL received on fd " << pfd.fd << ", resetting to -1" << std::endl;
pfd.fd = -1;
} }
} }
return some_closed;
} }

@ -72,7 +72,7 @@ public:
CTCClient() : CTCSocket(), m_Port(0) {} CTCClient() : CTCSocket(), m_Port(0) {}
~CTCClient() {} ~CTCClient() {}
bool Open(const std::string &address, const std::string &modules, uint16_t port); bool Open(const std::string &address, const std::string &modules, uint16_t port);
bool Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms); void Receive(std::queue<std::unique_ptr<STCPacket>> &queue, int ms);
bool ReConnect(); bool ReConnect();
private: private:

Loading…
Cancel
Save

Powered by TurnKey Linux.