cNetwork: Implemented connection shutdown and close.
This commit is contained in:
parent
9ffca12709
commit
d8ac99a037
@ -87,6 +87,9 @@ public:
|
||||
a_Address and a_AddrLen describe the remote peer that has connected. */
|
||||
cTCPLinkImpl(evutil_socket_t a_Socket, cCallbacksPtr a_LinkCallbacks, cServerHandleImpl * a_Server, const sockaddr * a_Address, int a_AddrLen);
|
||||
|
||||
/** Destroys the LibEvent handle representing the link. */
|
||||
~cTCPLinkImpl();
|
||||
|
||||
/** Queues a connection request to the specified host.
|
||||
a_ConnectCallbacks must be valid.
|
||||
The object must have been constructed by the right constructor (without the Socket param). */
|
||||
@ -98,8 +101,8 @@ public:
|
||||
virtual UInt16 GetLocalPort(void) const override { return m_LocalPort; }
|
||||
virtual AString GetRemoteIP(void) const override { return m_RemoteIP; }
|
||||
virtual UInt16 GetRemotePort(void) const override { return m_RemotePort; }
|
||||
virtual void Shutdown(void) override;
|
||||
virtual void Close(void) override;
|
||||
virtual void Drop(void) override;
|
||||
|
||||
protected:
|
||||
|
||||
@ -164,6 +167,9 @@ public:
|
||||
cTCPLink::cCallbacksPtr a_LinkCallbacks
|
||||
);
|
||||
|
||||
/** Closes the server, dropping all the connections. */
|
||||
~cServerHandleImpl();
|
||||
|
||||
/** Starts listening on the specified port.
|
||||
Both IPv4 and IPv6 interfaces are used, if possible. */
|
||||
bool Listen(UInt16 a_Port);
|
||||
@ -499,6 +505,15 @@ cTCPLinkImpl::cTCPLinkImpl(evutil_socket_t a_Socket, cTCPLink::cCallbacksPtr a_L
|
||||
|
||||
|
||||
|
||||
cTCPLinkImpl::~cTCPLinkImpl()
|
||||
{
|
||||
bufferevent_free(m_BufferEvent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** Schedules the actual connection request.
|
||||
Returns true on success, false on failure. */
|
||||
bool cTCPLinkImpl::Connect(const AString & a_Host, UInt16 a_Port, cNetwork::cConnectCallbacksPtr a_ConnectCallbacks)
|
||||
@ -556,20 +571,31 @@ bool cTCPLinkImpl::Send(const void * a_Data, size_t a_Length)
|
||||
|
||||
|
||||
|
||||
void cTCPLinkImpl::Close(void)
|
||||
void cTCPLinkImpl::Shutdown(void)
|
||||
{
|
||||
// TODO
|
||||
ASSERT(!"cTCPLinkImpl::Close(): Not implemented yet");
|
||||
#ifdef _WIN32
|
||||
shutdown(bufferevent_getfd(m_BufferEvent), SD_SEND);
|
||||
#else
|
||||
shutdown(bufferevent_getfd(m_BufferEvent), SHUT_WR);
|
||||
#endif
|
||||
bufferevent_disable(m_BufferEvent, EV_WRITE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cTCPLinkImpl::Drop(void)
|
||||
void cTCPLinkImpl::Close(void)
|
||||
{
|
||||
// TODO
|
||||
ASSERT(!"cTCPLinkImpl::Drop(): Not implemented yet");
|
||||
bufferevent_disable(m_BufferEvent, EV_READ | EV_WRITE);
|
||||
if (m_Server == nullptr)
|
||||
{
|
||||
cNetworkSingleton::Get().RemoveLink(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Server->RemoveLink(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -736,24 +762,38 @@ cServerHandleImpl::cServerHandleImpl(cNetwork::cListenCallbacksPtr a_ListenCallb
|
||||
|
||||
|
||||
|
||||
void cServerHandleImpl::Close(void)
|
||||
cServerHandleImpl::~cServerHandleImpl()
|
||||
{
|
||||
// Stop the listener sockets:
|
||||
evconnlistener_free(m_ConnListener);
|
||||
m_ConnListener = nullptr;
|
||||
if (m_ConnListener != nullptr)
|
||||
{
|
||||
evconnlistener_free(m_ConnListener);
|
||||
}
|
||||
if (m_SecondaryConnListener != nullptr)
|
||||
{
|
||||
evconnlistener_free(m_SecondaryConnListener);
|
||||
m_SecondaryConnListener = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cServerHandleImpl::Close(void)
|
||||
{
|
||||
// Stop the listener sockets:
|
||||
evconnlistener_disable(m_ConnListener);
|
||||
if (m_SecondaryConnListener != nullptr)
|
||||
{
|
||||
evconnlistener_disable(m_SecondaryConnListener);
|
||||
}
|
||||
m_IsListening = false;
|
||||
|
||||
// Close all connections:
|
||||
// Shutdown all connections:
|
||||
cTCPLinkImplPtrs Conns;
|
||||
std::swap(Conns, m_Connections);
|
||||
for (auto conn: Conns)
|
||||
{
|
||||
conn->Close();
|
||||
conn->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,12 +66,13 @@ public:
|
||||
virtual UInt16 GetRemotePort(void) const = 0;
|
||||
|
||||
/** Closes the link gracefully.
|
||||
The link will keep trying to send the queued data, then it will send the FIN packet. */
|
||||
virtual void Close(void) = 0;
|
||||
The link will send any queued outgoing data, then it will send the FIN packet.
|
||||
The link will still receive incoming data from remote until the remote closes the connection. */
|
||||
virtual void Shutdown(void) = 0;
|
||||
|
||||
/** Drops the connection without any more processing.
|
||||
Sends the RST packet, queued outgoing and incoming data is lost. */
|
||||
virtual void Drop(void) = 0;
|
||||
virtual void Close(void) = 0;
|
||||
|
||||
protected:
|
||||
/** Callbacks to be used for the various situations. */
|
||||
@ -95,7 +96,8 @@ public:
|
||||
// Force a virtual destructor for all descendants:
|
||||
virtual ~cServerHandle() {}
|
||||
|
||||
/** Stops the server, no more incoming connections will be accepted. */
|
||||
/** Stops the server, no more incoming connections will be accepted.
|
||||
All current connections will be shut down (cTCPLink::Shutdown()). */
|
||||
virtual void Close(void) = 0;
|
||||
|
||||
/** Returns true if the server has been started correctly and is currently listening for incoming connections. */
|
||||
|
@ -38,6 +38,16 @@ class cEchoLinkCallbacks:
|
||||
LOGD("%p (%s:%d): Data received (%u bytes), echoing back.", &a_Link, a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort(), static_cast<unsigned>(a_Size));
|
||||
a_Link.Send(a_Data, a_Size);
|
||||
LOGD("Echo queued");
|
||||
|
||||
// Search for a Ctrl+Z, if found, drop the connection:
|
||||
for (size_t i = 0; i < a_Size; i++)
|
||||
{
|
||||
if (a_Data[i] == '\x1a')
|
||||
{
|
||||
a_Link.Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnRemoteClosed(cTCPLink & a_Link) override
|
||||
@ -67,7 +77,7 @@ int main()
|
||||
ASSERT(Server->IsListening());
|
||||
|
||||
// Wait for the user to terminate the server:
|
||||
printf("Press enter to terminate the server.\n");
|
||||
printf("Press enter to close the server.\n");
|
||||
AString line;
|
||||
std::getline(std::cin, line);
|
||||
|
||||
@ -75,6 +85,10 @@ int main()
|
||||
LOG("Server terminating.");
|
||||
Server->Close();
|
||||
ASSERT(!Server->IsListening());
|
||||
LOGD("Server has been closed.");
|
||||
|
||||
printf("Press enter to exit test.\n");
|
||||
std::getline(std::cin, line);
|
||||
|
||||
LOG("Network test finished.");
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user