0

I'm familiarising myself with Unix Sockets for Inter-Process Communication, and following a guide here. Each time I run the program that acts as a server (referred to as echos.c in the guide), I am getting an error that says bind: Address already in use, except for the first time I run it after deleting all build files.

The error is coming from this section of code:

#define SOCK_PATH "echo_socket"

int main(void)
{
    int s, s2, len;
    socklen_t t;
    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);
    }

    // ...

In the initial run, the program creates a socket file called echo_socke (I have checked this with ls -l, and it is strange that the name is missing the 't' to make it echo_socket), and then goes on to successfully bind and listen for the client process.

However, in subsequent runs where I do not delete the build files, I get the error bind: Address already in use, coming from the lines

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

Doing additional testing I found that unlink(local.sun_path) is returning a No such file or directory error, so I figure the socket file that the bind is attempting to access is not being found. Could this be due to the file name missing a character as mentioned earlier? (But it works on the first time around, so it can't be?). Any help figuring out what is going on would be much appreciated.

user207421
  • 305,947
  • 44
  • 307
  • 483
Brendonovich
  • 57
  • 2
  • 4
  • 1
    You're calculating `len` incorrectly. See *man 7 unix.* It should be `offsetof(struct sockaddr_un, sun_path)+strlen(local.sun_path)+1`. – user207421 Oct 28 '19 at 02:09
  • @Nina This is AF_UNIX. There are no ports. – user207421 Oct 28 '19 at 02:12
  • @user207421 That did the trick, thankyou so much! – Brendonovich Oct 28 '19 at 02:22
  • Explanation is that `bind()` is expecting the length to contain the trailing null, as you can see from the formula. So it assumed that the last character *was* the trailing null and truncated the name. So your `unlink()` didn't unlink it, so it was still there, so 'address already in use'. You need to use the same formula when connecting of course. – user207421 Oct 28 '19 at 02:28
  • Ahhhhh, makes sense. The code I used was the same as in the tutorial, so I assumed it would be fine. Client works as well now, thanks! – Brendonovich Oct 28 '19 at 02:49
  • I should reword that. It assumes that the final character isn't part of the name, so it only uses `offsetof(struct sockaddr_un, sun_path)+strlen(local.sun_path)` bytes of the structure. Lousy design. They should not have required the +1. Too late now. – user207421 Oct 28 '19 at 02:51

0 Answers0