Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loopback example using INADDR_LOOPBACK does not work

I am trying to set a loopback socket in C but nothing works. I'm trying to make a function that opens a socket with the loopback address ,send data to socket and from another function read the data but nothing works. I believe that I don't know how to use the functions related to connections. Here is what I accomplished so far:

#include <sys/wait.h>       
#include <sys/types.h>       
#include <sys/socket.h>     
#include <netinet/in.h>       
#include <netdb.h>           
#include <unistd.h>             
#include <stdlib.h>         
#include <ctype.h>          
#include <signal.h>         
#include <iostream>
#include <cerrno>
#include <pthread.h>

int internal_s;

void function1(){
    if ((internal_s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        perror_exit("socket");

    /* Find server address */
    struct sockaddr_in loopback;
    struct sockaddr *serverptr = (struct sockaddr*)&loopback; 

    /*Convert port number to integer*/        
    loopback.sin_family = AF_INET;       /* Internet domain */
    loopback.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    loopback.sin_port=htons(10000);

    /* Initiate connection */
    if (bind(internal_s,serverptr, sizeof(loopback))<0)
        perro("bind");

    int test=1;
    err=write(internal_s,&test,sizeof(int));
    if(err<0)
        perror(write);
}

void Open_Internal_sock(int socket_s){
    struct sockaddr_in loopback;
    struct sockaddr *serverptr = (struct sockaddr*)&loopback; 

    /*Convert port number to integer*/        
    loopback.sin_family = AF_INET;       /* Internet domain */
    loopback.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    loopback.sin_port=htons(10000);

    /* Initiate connection */
    if (bind(socket_s,serverptr, sizeof(loopback))<0)
        perror("bind");//Invalid argument
    int test;
    if(read(socket_s,&test,sizeof(int))<0)
        perror("read");//herer it prints:Transport endpoint is not connected
}

int main(){
    function1(i);
    Open_Internal_sock(internal_s);
}
like image 975
JmRag Avatar asked May 28 '13 08:05

JmRag


People also ask

Why is the symbolic constant Inaddr_any used?

This is an IP address that is used when we don't want to bind a socket to any specific IP. Basically, while implementing communication, we need to bind our socket to an IP address. When we don't know the IP address of our machine, we can use the special IP address INADDR_ANY .

What is the value of Inaddr_any?

There are several special addresses: INADDR_LOOPBACK (127.0. 0.1) always refers to the local host via the loopback device; INADDR_ANY (0.0. 0.0) means any address for binding; INADDR_BROADCAST (255.255. 255.255) means any host and has the same effect on bind as INADDR_ANY for historical reasons.


1 Answers

In short, the client(sender, "writer") needs to call connect() and the server(listener, receiver, "reader") needs to cal listen() and accept().

The server and client also need separate threads of execution, because some of the socket operations block and would cause a single thread of execution to stop forever. Easiest is probably to make a server.c and client.c as separate programs.

Additionally, try compiling your code with warnings enabled, e.g., gcc -Wall . There are now quite many errors, which the compiler can point out for you. For clearer messages, try clang instead of gcc as a compiler.

I suggest looking at http://kohala.com/start/unpv12e/unpv12e.tar.gz . Unpack with tar xzvf unpv12e.tar.gz and look at unpv12e/tcpcliserv/tcpcli01.c and unpv12e/tcpcliserv/tcpserv01.c . In case you are tempted to copy&paste, notice that the Capital letters in, e.g., Listen() need to be changed to lower case for the code to work without unpv headers. This change also removes all checks for errors, so put in your own error handling.

like image 107
thuovila Avatar answered Oct 08 '22 05:10

thuovila