Samuele Calugi
Samuele Calugi

Reputation: 29

Which options is the best for send/receive packet in AF UNIX?

In a AF_UNIX socket connection where I have to send/receive a packet from a server, which of these options is the best solution and why? Thank you!

Client Main

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <pthread.h>

#include <unistd.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define UNIX_PATH_MAX 108 
#define SOCKNAME "../../mysock"

// used only in option 3
typedef struct Packet {
    int id;
    int length;
    char *message;
} Packet;

int main(void) {
    int fd_skt, fd_c;
    char buf[N];
    struct sockaddr_un sa;
    strncpy(sa.sun_path, SOCKNAME, UNIX_PATH_MAX);
    sa.sun_family = AF_UNIX;

    fd_skt = socket(AF_UNIX,SOCK_STREAM,0);

    while (connect(fd_skt, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
        if (errno == ENOENT) {
            printf("NONE!");
            sleep(1);
        } else
            exit(EXIT_FAILURE);
    }

    int id = 3;
    char message[6] = "hello"; // h e l l o \0
    int length = strlen(message) + 1;

Option 1: send the packet with 3 different write

    /**
     * Send the packet with 3 different write
     */

    write(fd_skt, &id, sizeof(int));
    write(fd_skt, &length, sizeof(int));
    write(fd_skt, message, length);

    sleep(5);
    read(fd_skt, buf, N);
    printf("Client got : %s\n", buf);
    close(fd_skt);

    return 0;
}

Option 2: create a buffer, using memcpy to put data in the buffer, send first the buffer size to the server, and after the whole packet

    /**
     * Create a buffer, using memcpy to put data in the buffer, send first the buffer size to the server, and after the whole packet
     */

    int size = strlen(message) + 1 + sizeof(int) + sizeof(int);
    void *buffer = malloc(sizeof(size));

    memcpy(buffer, &id, sizeof(int));
    memcpy(buffer + 4, &length, sizeof(int));
    memcpy(buffer + 8, message, length);

    write(fd_skt, &size, sizeof(int));
    write(fd_skt, buffer, size);

    sleep(5);
    read(fd_skt, buf, N);
    printf("Client got : %s\n", buf);
    close(fd_skt);

    return 0;
}

Option 3: create the packet using a struct (the server has the same struct), send first the packet size to the server and after send the struct, casting it as (void *) &packet

    /**
     * Create the packet using a struct (the server has the same struct), send first the packet size to the server and after send the struct, casting it as (void *) &packet
     */

    int size = strlen(message) + 1 + sizeof(int) + sizeof(int);

    Packet packet;
    packet.id = id;
    packet.length = length;
    packet.message = "hello";

    write(fd_skt, &size, sizeof(int));
    write(fd_skt, (void *) &packet, size);

    sleep(5);
    read(fd_skt, buf, N);
    printf("Client got : %s\n", buf);
    close(fd_skt);

    return 0;
}

Upvotes: 0

Views: 128

Answers (1)

fpiette
fpiette

Reputation: 12322

There is no real different between each method. Select the one that makes your program more readable. Performance is mostly implementation dependent.

Having a single write() will make sure that the data will be sent using the minimum number of packets on the wire which is the fastest way to transmit if data quality on the wire is very good.

Upvotes: 1

Related Questions