1

The following code is a programming sample for using UDP sockets.

There are 3 .c source files (Client_UDP.c, Server_UDP.c, and Message_UDP.c), and 1 .h header file (Prototype.h).

I want the Server and Client to communicate with each other only through the functions in Message_UDP.

The course of events seems to be like this:

  1. The Client sends a first packet/message to the Server.
  2. The Server receives the packet from the Client.
  3. The Server tries to send a response package, but shows an error: "Error in sendto(): Address family not supported by protocol".

Does anyone know why? How can I solve this?

Client_UDP.c

#include <stdio.h>      
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "Prototype.h"

int main(int argc, char * argv[]) {

    int fd_socket;

    struct sockaddr_in server;      
    socklen_t length_server = sizeof (server);

    fd_socket = socket(AF_INET, SOCK_DGRAM, 0);
    Error_A(fd_socket, "Error in socket()");

    server.sin_port = htons(8888);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("127.0.0.1");

    // send packet to server
    function_SEND(fd_socket, server, length_server, "CLIENT");

    // receive packet from server
    function_RECEIVE(fd_socket, server, length_server, "CLIENT");

    close(fd_socket);
    return EXIT_SUCCESS;
}

Server_UDP.c

#include <stdio.h>      
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "Prototype.h"

int main(int argc, char * argv[]) {

    int fd_socket;
    int rv; // return value

    struct sockaddr_in server;
    struct sockaddr_in client;

    socklen_t length_server = sizeof (server);
    socklen_t length_client = sizeof (client);

    fd_socket = socket(AF_INET, SOCK_DGRAM, 0);
    Error_A(fd_socket, "Errore in socket()");

    server.sin_port = htons(8888);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;

    rv = bind(fd_socket, (struct sockaddr *) &server, length_server);
    Error_A(rv, "Error in bind()");

    // receive packet from client
    function_RECEIVE(fd_socket, client, length_client, "SERVER");

    // send packet to client
    function_SEND(fd_socket, client, length_client, "SERVER");

    close(fd_socket);
    return EXIT_SUCCESS;
}

Message_UDP.c

#include <stdio.h>      
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "Prototype.h"

void Error_A(int return_value, char *error_message) {

    if (return_value < 0) {
        perror(error_message);
        exit(EXIT_FAILURE);
    }
}

void function_SEND(int fd_socket, struct sockaddr_in host, int length_host, char *sender) {

    int rv; // return value
    char packet[100] = "PACKET";

    // send packet
    rv = sendto(fd_socket, packet, 100, 0, (struct sockaddr *) &host, length_host);
    Error_A(rv, "Error in sendto()");
    printf("<%s> -- package sent: <%s> \n", sender, packet);
}

void function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver) {

    int rv; // return value
    char packet[100] = "";

    // receive packet
    rv = recvfrom(fd_socket, packet, 100, 0, (struct sockaddr *) &host, &length_host);
    Error_A(rv, "Errore in recvfrom()");
    printf("<%s> -- packet received: <%s> \n", receiver, packet);
}

Prototype.h

void Error_A(int return_value, char *error_message);

void function_SEND(int fd_socket, struct sockaddr_in host, int length_host, char *sender);

void function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver);

This is the client output:

CLIENT -- package sent: PACKET

This is the server output:

SERVER -- package received: PACKET

Error in sendto(): Address family not supported by protocol

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Leonardo
  • 89
  • 1
  • 10
  • Unrelated to your problem, but you do know that the port number should be in network byte order? I.e. you need to use e.g. `server.sin_port = htons(8888);` – Some programmer dude Aug 26 '18 at 14:54
  • Much more related to your problem, don't forget that arguments to functions in C are passed *by value*. That means the arguments in a function are *copies* of the original values passed in. Modifying a copy does not modify the original. Think a little about why you need to pass a *pointer* to the socket address structure in the call to `recvfrom`, and do some research about *emulating pass by reference in C*. – Some programmer dude Aug 26 '18 at 14:56
  • no sorry...i correct it now – Leonardo Aug 26 '18 at 15:52
  • Do you means to create a pointer to structure like this 'struct sockaddr_in *client' and then modify the function 'function_RECEIVE()' to pass it? – Leonardo Aug 26 '18 at 15:53
  • No, `client` can still be a structure object like now, but you should modify your `function_RECEIVE` to expect a pointer, and pass it like you pass the structure to `recvfrom`. – Some programmer dude Aug 26 '18 at 15:55
  • I modified the ''function_RECEIVE'', now it should work – Leonardo Aug 26 '18 at 16:46

2 Answers2

0

I may be missing something obvious. Here is something I noted. In your Server_UDP.c, there is no initializion for the client. I see the declaration struct sockaddr_in client;, but there is no assignment. Here, I would assume the client would be assigned the same port number and the loop back IP address, like the following

client.sin_port = 8888;
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr("127.0.0.1");

This could be why the send is failing in the server

Ravi S
  • 139
  • 3
  • You're *partially* correct, in that the `client` structure isn't initialized. However it's not like that it's supposed to be initialized, instead it should be initialized by a call to `recvfrom` which doesn't happen because of the reason pointed out in my second comment to the question. – Some programmer dude Aug 26 '18 at 15:19
  • yes it works in part! the Server sends the packet, but now is the Client that do not receives the packet! – Leonardo Aug 26 '18 at 15:55
0

I add this structure in the Prototype.h:

struct Host {
    struct sockaddr_in host;
    socklen_t length_host;
} host_return;

void Error_A(int return_value, char *error_message);

void function_SEND(int fd_socket, struct sockaddr_in host, int length_host, char *sender);

struct Host function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver);

Changing the function_RECEIVE() in Message_UDP.c with this:

struct Host function_RECEIVE(int fd_socket, struct sockaddr_in host, int length_host, char* receiver) {

    int rv; // return value
    char packet[100] = "";

    // receive packet
    rv = recvfrom(fd_socket, packet, 100, 0, (struct sockaddr *) &host, &length_host);
    Error_A(rv, "Errore in recvfrom()");
    printf("%s -- packet received: %s \n", receiver, packet);

    host_return.host = host;
    host_return.length_host = length_host;

    return host_return;
}

and the code in Server_UDP.c put this:

// receive packet from client
host_return = function_RECEIVE(fd_socket, client, length_client, "SERVER");
    
// send packet to client
function_SEND(fd_socket, host_return.host, host_return.length_host,"SERVER");

instead of

// receive packet from client
function_RECEIVE(fd_socket, client, length_client, "SERVER");

// send packet to client
function_SEND(fd_socket, client, length_client, "SERVER");

it seems to work because the output is (but i hope i don't have had just luck):

CLIENT -- packet sent: PACKET

CLIENT -- packet received: PACKET

server:

SERVER -- packet received: PACKET

SERVER -- packet sent: PACKET

Community
  • 1
  • 1
Leonardo
  • 89
  • 1
  • 10