5

I am beginner in python written first program two days ago. I am having connection problem in python client and C server for AF_UNIX. I have C socket Server with AF_LOCAL.

#define NAME "#/tmp/kvsd"

int
main()
{
    int sock, msgsock, rval;
    struct sockaddr_un server;
        char buf[1024];


        unlink(NAME);
        printf("before socket \n");
        sock = socket(AF_LOCAL, SOCK_STREAM, 0);
        if (sock < 0) {
                perror("opening stream socket");
                exit(1);
        }
        memset(&server, 0, (sizeof (server)));
        server.sun_family = AF_LOCAL;
        memcpy(server.sun_path, NAME, strlen(NAME));
        server.sun_path[0] = 0;
        printf("before bind \n");

        int len = strlen(server.sun_path) + sizeof(server.sun_family);
        if (bind(sock, (struct sockaddr *) &server, len)) {
                perror("binding stream socket");
                exit(1);
        }

        printf("before listen \n");
        if (listen(sock, 5) == -1) {
                perror("listen");
                exit(1);
        }
        printf("before accept \n");
        msgsock = accept(sock, 0, 0);
        printf("accepted \n");
        if (msgsock == -1)
                perror("accept");
        else do {
                bzero(buf, sizeof(buf));

                printf("before read  \n");
                if ((rval = read(msgsock, buf, 1024)) < 0)
                        perror("reading stream message");
                else if (rval == 0)
                        printf("Ending connection\n");
                else
                        printf("-->%s\n", buf);
        } while (rval > 0);
        close(msgsock);
        close(sock);
        unlink(NAME);
}

And Python AF_UNIX client.py:-

####### CLIENT CODE #######

from socket import *

# Create an unbond and not-connected socket.
sock = socket(AF_UNIX, SOCK_STREAM)

# Connect to the peer registered as "MyBindName" in the abstract namespace. Note the '\0'.
str = "\0/tmp/kvsd\0"

print "len ", len (str)
sock.connect("\0/tmp/kvsd")

# Wait for message
msg = sock.recv(100)
print msg

# Send reply
sock.send("Hi there!\n")

# Block until new message arrives
msg = sock.recv(100)

# When the socket is closed cleanly, recv unblocks and returns ""
if not msg:
    print "It seems the other side has closed its connection"

# Close it
sock.close()

But When I run the client I'm getting following error:

[root@mat afunix]# python ./client.py len 11 Traceback (most recent call last): File "./client.py", line 13, in sock.connect("\0/tmp/kvsd") File "", line 1, in connect socket.error: [Errno 111] Connection refused [root@mat afunix]#

I am trying to use the abstract namespaces for UNIX socket but my python client is not able to connect to c server.

I tried without abstract namespaces it works. (changed NAME macro in server.c to "/tmp/kvsd" and argument to sock.connect to "/tmp/kvsd").

Can someone help me to figure out what may be the exact issue ?

Thanks in advance.

1
  • 1
    Welcome to Stack Overflow! Thanks for asking this question. Please don't elide the #include statements in your example. It makes it hard for others to compile and test your code. Commented Jun 14, 2013 at 1:53

1 Answer 1

4

Following line has a problem.

    int len = strlen(server.sun_path) + sizeof(server.sun_family);

server.sun_path has now leading null character. So strlen(server.sun_path) is 0. You need change above line as follow:

    #include <stddef.h>

    ....

    int len = offsetof(struct sockaddr_un, sun_path) + strlen(NAME);

Then, it will work.

EDIT: updated the code to use offsetof to avoid padding issue. (Thank you, alk)

PS: I assume that both server, client use name without trailing null byte. If you use name with trailing null byte, add 1 to len.

Sign up to request clarification or add additional context in comments.

10 Comments

You are missing to add 1 for the 0-terminator. Also using offsetof(struct sockaddr_un, sun_path) + strlen(NAME) + 1 makes sure padding won't be an issue.
@alk offsetof(struct sockaddr_un, sun_path) + strlen(NAME) works. Adding + 1 does not work. Python(client part) does not terminate string with null byte unlike C.
The server is coded in C, the call to bind() is a C system call, isn't it? Did you test it does not work with +1?
@alk, Yes, I tested it. With + 1, Python client can't connect to server. Server, client should agree with name.
If my explanation was not good due to my poor English, read following blog post. (especially Note for C programmers part) AF_UNIX sockets and the abstract namespace, inter-process communication.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.