User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

c:subserv [2019-05-24 12:24] (current)
ziggi created
Line 1: Line 1:
  
 +=====Master-slave pair of processes with Unix datagram communication=====
 +
 +===mainserv.c===
 +
 +<code C mainserv.c>​
 +/*
 + * Copyright 2011 Oleg Borodin ​ <​onborodin@gmail.com>​
 + */
 +
 +#include <​sys/​types.h>​
 +#include <​sys/​socket.h>​
 +#include <​sys/​un.h>​
 +#include <​sys/​wait.h>​
 +#include <​signal.h>​
 +
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​unistd.h>​
 +#include <​string.h>​
 +#include <​stdbool.h>​
 +
 +int main(int argc, char **argv) {
 +
 +    pid_t pid = fork();
 +    if (pid == 0){
 +        /* in the child */
 +        char subserv[] = "​./​subserv";​
 +
 +        char* args[] = { subserv, NULL };
 +        int res = execv(subserv,​ args);
 +
 +        fprintf(stderr,​ "exec res %d\n", res);
 +    }
 +    if (pid < 0) {
 +        fprintf(stderr,​ "​unable fork, exit\n"​);​
 +        exit(1);
 +    }
 +
 +    int sock = -1;
 +    if((sock = socket(AF_UNIX,​ SOCK_DGRAM, 0)) < 0) {
 +        fprintf(stderr,​ "​unable create unix socket, exit\n"​);​
 +        exit(1);
 +    }
 +
 +    const char sockpath[] = "​unix-socket";​
 +
 +    struct sockaddr sockaddr;
 +    memset(&​sockaddr,​ 0, sizeof(struct sockaddr));
 +
 +    struct sockaddr_un* paddr = (struct sockaddr_un*)&​sockaddr;​
 +    paddr->​sun_family = AF_UNIX;
 +    strcpy(paddr->​sun_path,​ sockpath);
 +
 +    socklen_t socklen = sizeof(struct sockaddr_un);​
 +
 +    sleep(1);
 +
 +    if (connect(sock,​ (struct sockaddr*)&​sockaddr,​ socklen) < 0) {
 +        fprintf(stderr,​ "​unable connect to unix socket, exit.\n"​);​
 +        exit(1);
 +    }
 +
 +    fprintf(stderr,​ "​connect to unix socket %d\n", sock);
 +
 +    while(true) {
 +        const char msg[] = "​hello,​ subprocess!";​
 +        fprintf(stderr,​ "try send to subprocess\n"​);​
 +
 +        ssize_t res = send(sock, msg, strlen(msg),​ 0);
 +
 +        fprintf(stderr,​ "send %d chars\n",​ (int)res);
 +        sleep(1);
 +    }
 +    close(sock);​
 +
 +    kill(pid, SIGTERM);
 +
 +    int status;
 +    waitpid(pid,​ &​status,​ 0);
 +
 +    return 0;
 +}
 +</​code>​
 +
 +===subserv.c===
 +
 +<code C subserv.c>​
 +/*
 + * Copyright 2011 Oleg Borodin ​ <​onborodin@gmail.com>​
 + */
 +
 +#include <​sys/​types.h>​
 +#include <​sys/​socket.h>​
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​unistd.h>​
 +#include <​sys/​un.h>​
 +#include <​string.h>​
 +
 +
 +int main(int argc, char **argv) {
 +
 +    int sock = -1;
 +    if((sock = socket(AF_UNIX,​ SOCK_DGRAM, 0)) < 0) {
 +        fprintf(stderr,​ "​unable create unix socket, exit\n"​);​
 +        exit(1);
 +    }
 +
 +    const char sockpath[] = "​unix-socket";​
 +
 +    struct sockaddr sockaddr;
 +    memset(&​sockaddr,​ 0, sizeof(struct sockaddr));
 +
 +    struct sockaddr_un* paddr = (struct sockaddr_un*)&​sockaddr;​
 +    paddr->​sun_family = AF_UNIX;
 +    strcpy(paddr->​sun_path,​ sockpath);
 +
 +    unlink(sockpath);​
 +
 +    socklen_t socklen = sizeof(struct sockaddr_un);​
 +
 +    if (bind(sock, (struct sockaddr*)paddr,​ socklen) < 0) {
 +        fprintf(stderr,​ "​unable bind unix socket, exit\n"​);​
 +        close(sock);​
 +        exit(1);
 +    }
 +    int backlog = 1024;
 +    if (listen(sock,​ backlog) < 0) {
 +        fprintf(stderr,​ "​unable listen unix socket, exit\n"​);​
 +        close(sock);​
 +        exit(1);
 +    }
 +
 +    fprintf(stderr,​ "do accept with socket %d\n", sock);
 +
 +    ssize_t res;
 +    const int bufsize = 1024;
 +    char buffer[bufsize];​
 +
 +    while ((res = recv(sock, buffer, bufsize, 0)) > 0) {
 +
 +        char str[] = "";​
 +        strncat(str,​ buffer, (int)res);
 +
 +        fprintf(stderr,​ "​subprocess read %d chars: %s\n", (int)res, str);
 +    }
 +
 +    close(sock);​
 +    unlink(sockpath);​
 +
 +    return 0;
 +}
 +</​code>​
 +
 +===out===
 +
 +<​file>​
 +$ ./mainserv
 +do accept with socket 3
 +connect to unix socket 3
 +try send to subprocess
 +send 18 chars
 +subprocess read 18 chars: hello, subprocess!
 +try send to subprocess
 +send 18 chars
 +subprocess read 18 chars: hello, subprocess!
 +^C
 +</​file>​