Ahmed Sayed wrote:If i changed the timeout to 100 MS sure the process will get slower and it still timeout from time to time like giving me 7 timeouts in 1 minute during monitoring 4 servers.
That is to be expected, as even 100ms may be too short at times. There is overhead in establishing a new TCP connection (3-way handshake), as well as overhead in how Indy implements its ConnectTimeout (using a worker thread). So, you really should specify a timeout in seconds rather than in milliseconds.
For that matter, since you are doing real-time monitoring, why drop a connection and reconnect at 500ms intervals at all? Why not just establish a connection and leave it open? You will be notified if the connection is closed, such as when the server is shut down or killed.
Otherwise, I would suggest using the socket API directly to cut down on overhead, eg:
Code: Select all
#include <winsock2.h>
#include <ws2tcpip.h>
#include <vector>
#include <memory>
struct SocketDeleter
{
typedef SOCKET pointer;
void operator()(SOCKET s) const
{
if (s != INVALID_SOCKET)
{
int err = WSAGetLastError();
closesocket(s);
WSASetLastError(err);
}
}
};
bool SocketIsOpen(const UnicodeString &Host, short Port, String &Msg, int ATimeout)
{
Msg = _D("");
try
{
ADDRINFOW hints = {}, *addrs;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (GetAddrInfoW(Host.c_str(), UnicodeString(Port).c_str(), &hints, &addrs) != 0)
RaiseLastOSError(WSAGetLastError());
std::vector<std::unique_ptr<SOCKET, SocketDeleter>> sockets;
{
std::unique_ptr<ADDRINFOW, decltype(&::FreeAddrInfoW)> addrs_deleter(addrs, &FreeAddrInfoW);
for (ADDRINFOW *addr = addrs; addr != NULL; addr = addr->ai_next)
{
SOCKET sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sock != INVALID_SOCKET)
{
std::unique_ptr<SOCKET, SocketDeleter> sock_deleter(sock);
u_long mode = 1;
if (ioctlsocket(sock, FIONBIO, &mode) == 0)
{
connect(sock, addr->ai_addr, addr->ai_addrlen);
if (WSAGetLastError() == WSAEWOULDBLOCK)
sockets.push_back(std::move(sock_deleter));
}
}
}
if (sockets.empty())
RaiseLastOSError(WSAGetLastError());
}
fd_set fds;
FD_ZERO(&fds);
for(auto &sock : sockets) {
FD_SET(sock.get(), &fds);
}
timeval tv = {};
tv.tv_sec = ATimeout / 1000;
tv.tv_usec = (ATimeout & 1000) * 1000;
int err = select(0, NULL, &fds, NULL, &tv);
if (err < 0)
RaiseLastOSError(WSAGetLastError());
return (err > 0);
}
catch (const Exception &E)
{
Msg = E.Message;
return false;
}
}
//---------------------------------------------------------------------------