UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » General
  • » Interprocess communication using UNIX Domian Socket ?

#1 2014-05-07 10:37 AM

Ramesh_P
Member
Registered: 2014-03-13
Posts: 3

Interprocess communication using UNIX Domian Socket ?

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "echo_socket"

int main(void)
{
    int s, s2, t, len;
    struct sockaddr_un local, remote;
    char str[100];

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    local.sun_family = AF_UNIX;
    strcpy(local.sun_path, SOCK_PATH);
    unlink(local.sun_path);
    len = strlen(local.sun_path) + sizeof(local.sun_family);
    if (bind(s, (struct sockaddr *)&local, len) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(s, 5) == -1) {
        perror("listen");
        exit(1);
    }

    for(;;) {
        int done, n;
        printf("Waiting for a connection...\n");
        t = sizeof(remote);
        if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
            perror("accept");
            exit(1);
        }

        printf("Connected.\n");

        done = 0;
        do {
            n = recv(s2, str, 100, 0);
            if (n <= 0) {
                if (n < 0) perror("recv");
                done = 1;
            }

            if (!done) 
                if (send(s2, str, n, 0) < 0) {
                    perror("send");
                    done = 1;
                }
        } while (!done);

        close(s2);
    }

    return 0;
}

Offline

#2 2014-05-07 01:03 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,847
Website

Re: Interprocess communication using UNIX Domian Socket ?

Are you saying that the connect() in the client and accept() in the server both happen successfully, but nothing is ever read by the server's recv(), or is it the client's recv() that never gets the reply?

I just tested your exact code, and as long as I run both client and server in the same directory, they seem to work fine...  If you run them in different directories, they won't work, because you use a relative path for the socket name, so it's always going to be taken relative to the current directory of the process...  You could solve that by using a full path like "/tmp/echo_socket" or something...

But, I spot a couple issues with your code, anyway...  Add <unistd.h> to your #includes, for the prototype of unlink() and close()...  In the client, you either want to make your buffer 101 bytes in size or pass in 99 to recv(), since you add a null terminator based on the return value from recv()...  As it is, the server could theoretically send you a full 100 byte message and you'd overflow your buffer by adding the null byte...  Of course, in practice with your code as-is this is impossible, since you would never send it a message larger than 99 bytes in the first place, due to the fgets() limiting things to that at most...  But, just as a proactive security measure, it's a good idea to be wary of such practices...  Also, you're assuming that every send() corresponds to a single recv() on the other end, and that's not necessarily the case...  It's much more likely to work that way with Unix domain sockets than with TCP over the Internet, but it's still theoretically possible for a single large send() to require multiple recv()'s to read in full, or for a single recv() to read messages from multiple send()'s, because you're dealing with a simple stream protocol...  If you want a discrete message protocol, use datagram sockets...  Or, do the work necessary for making them work over a stream protocol: either prefix them with a fixed-size header giving the full length to read (and then read that exact amount from the stream), or terminate them with some character or series of characters, and then keep reading until you spot that terminator (and no further)...  You already effectively have a terminator due to the way fgets() works: a newline character...  The trick is replacing the simple recv() with something that just reads until it sees that newline...  One simple approach is just read a single character at a time until the newline is seen, appending bytes to a buffer as you go...  Another is to use recv(MSG_PEEK) to search for the location of the newline in your receive buffer, and then do a plain flagless recv() to only read that much and no more...  Yet another is to have a buffering layer that just reads as much as it can, but only returns you the amount upto the newline, saving any extra for the start of the next message...  That latter behavior is essentially just what stdio does for you, so one solution is to just fdopen() the socket and use fgets() on it!

Offline

#3 2014-05-07 01:16 PM

Ramesh_P
Member
Registered: 2014-03-13
Posts: 3

Re: Interprocess communication using UNIX Domian Socket ?

Offline

#4 2014-05-07 08:18 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,847
Website

Re: Interprocess communication using UNIX Domian Socket ?

Offline

#5 2014-05-09 08:05 AM

Ramesh_P
Member
Registered: 2014-03-13
Posts: 3

Re: Interprocess communication using UNIX Domian Socket ?

thank q for your answer it helped me lot :)

Offline

  • Index
  • » General
  • » Interprocess communication using UNIX Domian Socket ?

Board footer

Powered by FluxBB