Reputation: 315
Code :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
// #include <thread>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
#define PORT 8888
#define BACKLOG 5
int main(int argc, char const *argv[]) {
int status;
struct addrinfo hints,
*res,
*temp;
char ipstr [INET6_ADDRSTRLEN];
int socket_fd;
memset (&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // Allows both IPv4 and IPv6
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // Allows automatic fill-up of IP (allows using localhost)
if ((status = getaddrinfo (NULL , "8000", &hints, &res)) != 0 ) {
cout << "[-] Error: " << gai_strerror (status) << endl;
exit (EXIT_FAILURE);
}
socket_fd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
if (socket_fd == -1) {
cout << "[-] Error : Socket couldn't be created" << endl;
exit (EXIT_FAILURE);
}
if (bind (socket_fd, res->ai_addr, res->ai_addrlen) == -1 ) {
cout << "[-] Error: Failed to bind to port" << endl;
exit (EXIT_FAILURE);
}
if (connect (socket_fd, res->ai_addr, res->ai_addrlen) == -1) {
cout << "[-] Error: Failed to connect to remote user" << endl;
exit (EXIT_FAILURE);
}
freeaddrinfo (res); // free the linked list returned by getaddrinfo ()
return 0;
}
The code is returning :
[-] Error: Failed to bind to port
It doesn't matter if I put NULL on getaddrinfo ()'s first parameter (making it listen to localHost) or to provide some address, it isn't able to bind port to socket. The port is available as I have tried by changing the value of port. What is wrong with the code ?
Upvotes: 0
Views: 10732
Reputation: 1181
The code is fine, so when the first time is executed everything works as expected. However, the subsequent execution of the same program will report
[-] Error: Failed to bind to port
If you run netstat --tcp --numeric | grep 8000
you will see that the socket on the port 8000 is in TIME_WAIT state:
bash-4.2$ netstat --tcp --numeric | grep 8000
tcp 0 0 127.0.0.1:8000 127.0.0.1:8000 TIME_WAIT
meaning that connection is closed, so it will be terminated in the timeout specified by the OS (four minutes by default). After the timeout expires, the program executes without the error (again only once).
Upvotes: 4
Reputation: 118292
Something here is not making sense. The shown code attempts to bind a socket to a port, then immediately connect
() to the same port. So, even if the bind works, connect
() will fail anyway, because nothing is listening on that port.
Now, the most likely reason why bind
() is failing is because after a socket gets terminated unexpectedly, the kernel will not allow the same port to be reused for a minute or so, for a number of security-related reasons that are too boring to discuss. The first time this code runs, the bind should succeed, but connect
() will fail, and the program will exit; then for the next minute or so, rerunning it will result in a bind
() failure from the kernel refusing to reuse the port.
To prevent this, you must explicitly set the SO_REUSEADDR
socket option. You will find plenty of examples in Google. This will allow you to rebind the same port immediately. Now, all you'll need to do is to figure out what exactly you hoped to accomplish with that connect
() call...
Upvotes: 1