I wrote a Unix Domain Socket in my study, so I'll leave a note.
Python
The difference from TCP is that socket.AF_UNIX
is specified at the time of socket
initialization, and the argument of .bind ()
is the path. However, if the specified file already exists, an error will occur, so ʻunlink ()just before
.bind ()`.
uds_server.py
#!/usr/bin/env python
import os
import signal
import socket
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
sock = socket.socket(socket.AF_UNIX)
os.unlink('test.uds')
sock.bind('test.uds')
sock.listen(10)
while True:
s, addr = sock.accept()
print "connected from:", addr
while True:
s.sendall("a"*60 + '\n')
C
Handling sockaddr_un
is a bit more cumbersome than Python. Note that sockaddr_un.sun_path
is short. It seems that you can't make a socket in a deep directory structure. Python also uses it internally after all, so you shouldn't be able to escape the path length limit.
uds_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <signal.h>
static char buf[] = "aaaaaaaaaaaaaaaaaa\n";
int main()
{
int r;
int listen_fd = 0;
struct sockaddr_un local, remote;
signal(SIGPIPE, SIG_IGN);
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
local.sun_family = AF_UNIX;
strcpy(local.sun_path, "test.uds");
unlink(local.sun_path);
r = bind(listen_fd, (struct sockaddr *)&local, sizeof(local));
if (r)
perror("failed to bind");
listen(listen_fd, 100);
for (;;) {
socklen_t len = sizeof(remote);
int remote_fd = accept(listen_fd, (struct sockaddr *)&remote, &len);
if (remote_fd < 0) {
perror("failed to accept");
return 0;
}
for (;;) {
int sent = write(remote_fd, buf, 20);
printf("sent %d bytes\n", sent);
if (sent < 0) {
printf("%d %s\n", errno, strerror(errno));
perror("fail to send");
close(remote_fd);
break;
}
}
}
}
Recommended Posts