I'm developing a c++ program in Ubuntu that works with tcp sockets and websockets (using boost) an has to be restarted whenever the program dies. All of this is working properly except for one thing:
Sometimes when the program dies and gets relaunched one of the ports used appears as "not available", however, running netstat -tulpn doesn't show any process using that port. My master program is set to wait until the port is available to relaunch the program and it eventually gets launched (ports take like 1 minute to be available again, maybe a bit less) and I'm wondering if this time without being able to access the port is something related to how I close them or can be avoided somehow. My only idea to help with this was to kill any process using the port but I haven't found anything that way.
This issue isn't a big problem, it just makes the program stay down for a little bit but if I could reduce this delay it would be great.
Thank you!
Edit:
To help with my reply below, this is the port setup that gets hung up:
int start_listener()
{
Logger* p_logger = NULL;
p_logger = Logger::get_instance();
string log;
int i_result;
int listener = -1;
struct addrinfo *result = NULL;
struct addrinfo hints;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
memset(&hints,0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
i_result = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (i_result != 0)
{
log="[server] getaddrinfo failed with error: {}"+errno;
p_logger->error(log);
return 1;
}
// Create a SOCKET for connecting to server
listener = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listener == -1)
{
log="[server] socket failed with error: {}"+errno;
p_logger->error(log);
freeaddrinfo(result);
return 1;
}
//Reuse ports faster
int reuse = 1;
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
{
p_logger->error("[server] setsockopt(SO_REUSEADDR) failed");
}
if (setsockopt(listener, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
{
p_logger->error("[server] setsockopt(SO_REUSEPORT) failed");
}
// Setup the TCP listening socket
i_result = bind(listener, result->ai_addr, (int)result->ai_addrlen);
if (i_result == -1)
{
log="[server] bind failed with error: {}"+errno;
p_logger->error(log); freeaddrinfo(result);
close(listener);
return 1;
}
freeaddrinfo(result);
i_result = listen(listener, SOMAXCONN);
if (i_result == -1)
{
log="[server] listen failed with error: {}"+errno;
p_logger->error(log);
close(listener);
return 1;
}
p_logger->info("[server] Waiting for client...");
socket = accept(listener, NULL, NULL);
if (socket == -1)
{
log="[server] accept failed with error: {}"+errno;
p_logger->error(log);
close(listener);
return 1;
}
p_logger->info("[server] client accepted");
while(true)
{
// Receive until the peer shuts down the connection
memset(recvbuf, 0, sizeof(recvbuf));
i_result = recv(socket, recvbuf, recvbuflen, 0);
if (i_result > 0)
{
if(!send_socket(convert_to_string(recvbuf, i_result)))
{
p_logger->error("[server] Impossible to send");
}
else
{
p_logger->debug("[server] Message received");
}
}
}
// shutdown the connection since we're done
i_result = shutdown(socket, SHUT_WR);
if (i_result == -1)
{
log="[server] shutdown failed with error: {}"+errno;
p_logger->error(log);
close(socket);
return 1;
}
// cleanup
close(socket);
return 0;
}
edit 2, Here's the other socket which works fine:
int start_server()
{
Logger* p_logger = NULL; // Create the object pointer for Logger Class
p_logger = Logger::get_instance();
string log;
int i_result;
int listen_socket = -1;
struct addrinfo *result = NULL;
struct addrinfo hints;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
memset(&hints,0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
i_result = getaddrinfo(NULL, DEFAULT_PORT_VISION, &hints, &result);
if (i_result != 0)
{
log="[server] getaddrinfo failed with error: {}"+errno;
p_logger->error(log);
return 1;
}
// Create a SOCKET for connecting to server
listen_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (listen_socket == -1)
{
log="[server] socket failed with error: {}"+errno;
p_logger->error(log);
freeaddrinfo(result);
return 1;
}
//Reuse ports faster
int reuse = 1;
if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
{
p_logger->error("[server] setsockopt(SO_REUSEADDR) failed");
}
if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
{
p_logger->error("[server] setsockopt(SO_REUSEPORT) failed");
}
// Setup the TCP listening socket
i_result = bind(listen_socket, result->ai_addr, (int)result->ai_addrlen);
if (i_result == -1)
{
log="[server] bind failed with error: {}"+errno;
p_logger->error(log);
freeaddrinfo(result);
close(listen_socket);
return 1;
}
freeaddrinfo(result);
i_result = listen(listen_socket, SOMAXCONN);
if (i_result == -1)
{
log="[server] listen failed with error: {}"+errno;
p_logger->error(log);
close(listen_socket);
return 1;
}
p_logger->info("[server] Waiting for client...");
client_socket = accept(listen_socket, NULL, NULL);
if (client_socket == -1)
{
log="[server] accept failed with error: {}"+errno;
p_logger->error(log);
close(listen_socket);
return 1;
}
p_logger->info("[server] Client accepted");
while(true)
{
// Receive until the peer shuts down the connection
memset(recvbuf, 0, sizeof(recvbuf));
i_result = recv(client_socket, recvbuf, recvbuflen, 0);
if (i_result > 0)
{
//printf("Bytes received: %d, buffer: %s\n", i_result, recvbuf);
if(!cmd_cam.recive_data(recvbuf, i_result))
{
p_logger->error("[server] Impossible to read the message");
}
}
}
// shutdown the connection since we're done
i_result = shutdown(client_socket, SHUT_WR);
if (i_result == -1)
{
log="[server] shutdown failed with error: {}"+errno;
p_logger->error(log);
close(client_socket);
return 1;
}
// cleanup
close(client_socket);
return 0;
}