开发者

C and Python - communicating with sockets

开发者 https://www.devze.com 2023-03-22 09:41 出处:网络
I\'m trying to use UNIX domain sockets to communicate between a C program, and a Python script. The Python script sends data via UNIX domain sockets to the C program.

I'm trying to use UNIX domain sockets to communicate between a C program, and a Python script. The Python script sends data via UNIX domain sockets to the C program.

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开发者_StackOverflow社区((connection_fd = accept(socket_fd, 
                            (struct sockaddr *) &address,
                            &address_length)) > -1)
{
.
.
.(doesn't get any further than this)

This is the python script I am using to send a message to the 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()

The python script fails with the error "Broken Pipe". The C program never enters the while loop because the accept() function fails and returns '-1'.

Why is accept() failing? And what can I do to make it succeed?


Looking at an example I found, it seems that the length you pass bind should not count the terminating or padding nulls in the 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;
}

P.S. Because of this, you don't need the memset call.


IIRC, address_length needs to be initialized to the size of sockaddr_un before the accept() call. During the call, it is loaded with the actual length of the peer address that is shoved into address.

Rgds, Martin

0

精彩评论

暂无评论...
验证码 换一张
取 消