Question

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].

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top