I am trying to create a local connection between threads of the same process using a socket of AF_INET family.
The server is supposed to handle clients and serve their requests via multiplexing with threads.
So at the server's main thread I have this for the external connection: (checking for errors is omitted for keeping the length of the post reasonable)
struct sockaddr_in server_addr;
struct sockaddr *serverptr=(struct sockaddr *)&server_addr;
listening_sock = socket(AF_INET, SOCK_STREAM, 0);
fds[0].fd = listening_sock;
fds[0].events = POLLIN;
// Setting listening socket
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
int one = 1;
setsockopt(listening_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
setsockopt(listening_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
bind(listening_sock, serverptr, sizeof(server_addr));
listen(listening_sock, 5);
and then using poll I am polling at the listening socket successfully (communicating with a client).
Now I want to create an internal socket via TCP for communication between the main thread and a new thread I'll create.
I've added these:
struct sockaddr_in loopback_addr;
struct sockaddr *loopbackptr=(struct sockaddr *)&loopback_addr;
loopback_sock = socket(AF_INET, SOCK_STREAM, 0); //checking for errors is omitted
fds[1].fd = loopback_sock;
fds[1].events = POLLIN;
// Setting loopback socket
loopback_addr.sin_addr.s_addr = htonl(IN_LOOPBACKNET);
loopback_addr.sin_family = AF_INET;
loopback_addr.sin_port = htons(18000);
int one = 1;
setsockopt(loopback_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one));
setsockopt(loopback_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
bind(loopback_sock, loopback_ptr, sizeof(loopback_addr));
listen(loopback_sock, 5);
And also increased the nfds counter to 2.
Now the thread starts before the loop of poll and tries to communicate with this code:
struct sockaddr_in server;
struct sockaddr *serverptr = (struct sockaddr*)&server;
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("thread: socket");
pthread_exit((void*)-1);
}
int port = 18000;
server.sin_family = AF_INET;
server.sin_addr.s_addr = IN_LOOPBACKNET;
server.sin_port = htons(port);
if (connect(sock, serverptr, sizeof (server)) < 0)
{
perror("thread: connect");
pthread_exit((void*)-1);
}
And what happens is that connect syscall returns thread: connect: Network is unreachable
.
At the server's main loop I have this:
if (fd[1].revents)
printf("Loopback socket\n");
to check whether there is any interraction with this socket, but this never prints out anything.
I am not sure how to set up the internal socket, if there is a tutorial I could read, a link would be more than welcome!
It might be something simple, but as I am new to socket programming I cannot find it.
Edit:
After changing the IN_LOOPBACKNET to htonl(INADDR_LOOPBACK) as alk proposed, connect still fails but with a new message, connection refused
.
But still, there are no revents from the fds[2].
From the error message (Network is unreachable
) you could have conclude that there is something fishy with addressing.
So you might like to change
IN_LOOPBACKNET
to be
INADDR_LOOPBACK
The former resolves to 127
which most likely is not what you want, as it's the local loopback network.
The latter suits better as it resolves to 0x7f000001
, which ist the integer representation of the loopback address 127.0.0.1
.
Also you are missing the conversion to network byte order (htonl()
) when assigning the ip-address the client shall connect to.