C and Python - socket communication

I am trying to use UNIX domain sockets for communication between a C program and a Python script. Python script sends data through UNIX domain sockets to C.

Here is the relevant code from my C program:

#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/un.h> #include <sys/types.h> #include <sys/socket.h> #define UNIX_PATH_MAX 100 int main(void) { struct sockaddr_un address; int socket_fd, connection_fd; socklen_t address_length; pid_t child; socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (socket_fd < 0){ printf("socket() failed\n"); return 1; } unlink("/tmp/demo_socket"); memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; snprintf(address.sun_path, UNIX_PATH_MAX, "/tmp/demo_socket"); if (bind(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { printf("bind() failed\n"); return 1; } if(listen(socket_fd, 5) != 0) { printf("listen() failed\n"); return 1; } //----------------WHILE LOOP-----------------------> while((connection_fd = accept(socket_fd, (struct sockaddr *) &address, &address_length)) > -1) { . . .(doesn't get any further than this) 

This is a python script I use to send a message to a socket:

 import socket s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("/tmp/demo_socket") print "Sending..." s.send("Hello world") x = s.recv(1024) print x s.close() 

Python script error with "Broken Pipe" error. The C program never enters the while loop because the accept () function does not work and returns "-1".

Why does accept () not work? And what can I do to succeed?

+7
source share
2 answers

Looking at the example I found , it seems that the length you pass to bind should not calculate trailing or padding zeros in sockaddr_un .

Try:

 size_t addrlen; const char* sockname = "/tmp/demo_socket"; /* ... */ address.sun_family = AF_UNIX; snprintf(address.sun_path, UNIX_PATH_MAX, sockname); addrlen = sizeof(address.sun_family) + strlen(sockname); if (bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) { printf("bind() failed\n"); return 1; } 

PS Because of this, you do not need a memset call.

+2
source

IIRC, address_length must be initialized to the size of sockaddr_un before calling accept() . During a call, it boots with the actual address length of the peer, which locks into address .

Rgds, Martin

+2
source

All Articles