Unix Sockets¶
A simple client and server can be set-up with the following code.
C Server¶
This code has been modified using the example given in the Linux documentation.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "connection.h"
int
main(int argc, char *argv[])
{
struct sockaddr_un name;
int down_flag = 0;
int ret;
int connection_socket;
int data_socket;
char buffer[BUFFER_SIZE];
/* Create local socket. */
connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (connection_socket == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
/*
* For portability clear the whole structure, since some
* implementations have additional (nonstandard) fields in
* the structure.
*/
memset(&name, 0, sizeof(name));
/* Bind socket to socket name. */
name.sun_family = AF_UNIX;
strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1);
ret = bind(connection_socket, (const struct sockaddr *) &name,
sizeof(name));
if (ret == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
/*
* Prepare for accepting connections. The backlog size is set
* to 20. So while one request is being processed other requests
* can be waiting.
*/
ret = listen(connection_socket, 20);
if (ret == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
/* This is the main loop for handling connections. */
for (;;) {
/* Ensure buffer is zero'd*/
memset(buffer, 0, sizeof(buffer));
/* Wait for incoming connection. */
data_socket = accept(connection_socket, NULL, NULL);
if (data_socket == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
for (;;) {
/* Wait for next data packet. */
ret = read(data_socket, buffer, sizeof(buffer));
if (ret == -1) {
perror("read");
exit(EXIT_FAILURE);
}
/* Ensure buffer is 0-terminated. */
buffer[sizeof(buffer) - 1] = 0;
/* Handle commands. */
printf("%s\n", buffer);
if (!strncmp(buffer, "SEND", sizeof(buffer))) {
printf("Sending Data\n");
break;
}
if(!strncmp(buffer, "DOWN", sizeof(buffer))){
printf("Closing Program");
down_flag = true;
break;
}
}
sprintf(buffer, "Hello World!\n");
int buf_size = strlen(buffer);
/* Send Sizeof Buffer */
printf("Sending buffer of size: %d\n", buf_size);
ret = write(data_socket, &buf_size, sizeof(buf_size));
if (ret == -1) {
perror("write");
exit(EXIT_FAILURE);
}
/*Send Buffer */
printf("Sending contents of Buffer\n");
ret = write(data_socket, buffer, sizeof(buffer));
if (ret == -1) {
perror("write");
exit(EXIT_FAILURE);
}
/* Close socket. */
close(data_socket);
/* Quit on DOWN command. */
if (down_flag) {
break;
}
}
close(connection_socket);
/* Unlink the socket. */
unlink(SOCKET_NAME);
exit(EXIT_SUCCESS);
}
The connection.h
file:
#define SOCKET_NAME "/tmp/9Lq7BNBnBycd6nxy.socket"
#define BUFFER_SIZE 1500
Python Client¶
This client code requests the buffer from the server.
import socket
import sys
ADDRESS = "/tmp/9Lq7BNBnBycd6nxy.socket"
sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
sock.connect(ADDRESS)
sock.send(b"SEND")
len_data_bytes = sock.recv(4)
len_data = int.from_bytes(len_data_bytes, sys.byteorder, signed=True)
print(len_data)
data = sock.recv(len_data)
print(data.decode())