Unix Socket span docker and host

root@ubuntu:~/c++# ./u_server 
Listener on port /tmp/echo_socket 
Waiting for connections ...
Welcome message sent successfully
Adding to list of sockets as 0
Welcome message sent successfully
Adding to list of sockets as 1
recv failed: Connection reset by peer
recv failed: Connection reset by peer
Welcome message sent successfully
Adding to list of sockets as 0
Welcome message sent successfully
Adding to list of sockets as 1
recv failed: Connection reset by peer
recv failed: Connection reset by peer
^C

server

root@ubuntu:~/c++# cat u_server.c 
#include <stdio.h>
#include <stdint.h>
#include <string.h>   //strlen
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>   //close
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
 #include <sys/stat.h>
#include <netinet/in.h>
#include <sys/time.h> //FD_SET, FD_ISSET, FD_ZERO macros

#include<pthread.h> //for threading , link with lpthread

#include <fcntl.h>

#define SOCK_PATH "/tmp/echo_socket"

bool daemonize() {
    int res = fork();
    if (res < 0) {
        perror("fork");
        return false;
    }

    if (res != 0)
        _exit(0);

    // Now we're running as the daemon...
    res = setsid();
    if (res < 0) {
        perror("setsid");
        return false;
    }

    if (false) {
        int fd = open("/dev/null", O_RDWR, 0);
        if (fd >= 0) {
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            if (fd > 2)
                close(fd);
        }
    }

    return true;
}
 
/*
 * This will handle connection for each client
 * */
void *connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int& sock = *(int*)socket_desc;
    int read_size;
    char client_message[2000];
     
    //Send some messages to the client
    const char *message = "Greetings! I am your connection handler
";
    write(sock , message , strlen(message));
     
    message = "Now type something and i shall repeat what you type 
";
    write(sock , message , strlen(message));
     
    //Receive a message from client
    while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
    {
        //end of string marker
                client_message[read_size] = '';
        printf("client sock %d and recv %s 
", sock, client_message);
                //Send the message back to client
        write(sock , client_message , strlen(client_message));

                //clear the message buffer
                memset(client_message, 0, 2000);
    }
     
    if(read_size == 0)
    {
        puts("Client disconnected");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        perror("recv failed");
    }
    
    //
    sock = 0;
         
    return 0;
}

int main(int argc , char *argv[])
{
    bool dflag = false;
    if (dflag && !daemonize()) {
        return -1;
    }
     
     
    int master_socket;
    int client_socket[30];
    int max_clients = 30;
    struct sockaddr_un address;
      
    //set of socket descriptors
    fd_set readfds;
   
    //initialize all client_socket[] to 0 so not checked
    memset(client_socket, 0, sizeof(client_socket));
      
    //create a master socket
    if( (master_socket = socket(AF_UNIX , SOCK_STREAM , 0)) == 0) 
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    
    unlink(SOCK_PATH);
    
     //type of socket created
    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, SOCK_PATH);
      
    size_t len = strlen(address.sun_path) + sizeof(address.sun_family);
    
    if (bind(master_socket, (struct sockaddr *)&address, len)<0) 
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    printf("Listener on port %s 
", SOCK_PATH);
     
    //try to specify maximum of 3 pending connections for the master socket
    if (listen(master_socket, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }
      
    //accept the incoming connection
    size_t addrlen = sizeof(address);
    puts("Waiting for connections ...");
     
    while(true) 
    {
        //clear the socket set
        FD_ZERO(&readfds);
  
        //add master socket to set
        FD_SET(master_socket, &readfds);
        int max_sd = master_socket;
         
        //add child sockets to set
        for (int i = 0 ; i < max_clients ; i++) 
        {
            //socket descriptor
            int sd = client_socket[i];
             
            //if valid socket descriptor then add to read list
            if(sd > 0)
                FD_SET( sd , &readfds);
             
            //highest file descriptor number, need it for the select function
            if(sd > max_sd)
                max_sd = sd;
        }
  
        //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely
        int activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);
    
        if ((activity < 0) && (errno != EINTR)) 
        {
            printf("select error");
        }
          
        //If something happened on the master socket , then its an incoming connection
        if (FD_ISSET(master_socket, &readfds)) 
        {
            int new_socket = 0;
            if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
            {
                perror("accept");
                exit(EXIT_FAILURE);
            }
          
           puts("Welcome message sent successfully");
              
            //add new socket to array of sockets
            for (int i = 0; i < max_clients; i++) 
            {
                //if position is empty
                if( client_socket[i] == 0 )
                {
                    client_socket[i] = new_socket;
                    printf("Adding to list of sockets as %d
" , i);
                    
                    pthread_t thread_id;
                    if( pthread_create( &thread_id , NULL ,  connection_handler , (void*) &client_socket[i]) < 0)
                    {
                        perror("could not create thread");
                        return 1;
                    }
                    pthread_detach(thread_id);
                    
                    break;
                }
            }
        }   

    }
      
    return 0;
} 

g++ -pthread  u_server.c  -o u_server

client

root@ubuntu:~/c++# cat u_client.c 
#include <stdlib.h>  
#include <stdio.h>  
#include <sys/types.h>
#include <sys/stat.h>
#include <stddef.h>  
#include <sys/socket.h>  
#include <sys/un.h>  
#include <errno.h>  
#include <string.h>  
#include <unistd.h>  
 
#define MAXLINE 80  
 
char *client_path = "client.socket";  
char *server_path = "/tmp/echo_socket";  
 
int main(int argc, char* argv[]) {  
    struct  sockaddr_un cliun, serun;  
    int len;  
    char buf[100];  
    int sockfd, n;  
 
    if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){  
        perror("client socket error");  
        exit(1);  
    }  
      
    // 一般显式调用bind函数,以便服务器区分不同客户端  
    memset(&cliun, 0, sizeof(cliun));  
    cliun.sun_family = AF_UNIX;  
    strcpy(cliun.sun_path, argv[2]);  
    len = offsetof(struct sockaddr_un, sun_path) + strlen(cliun.sun_path);  
    unlink(cliun.sun_path);  
    if (bind(sockfd, (struct sockaddr *)&cliun, len) < 0) {  
        perror("bind error");  
        exit(1);  
    }  
 
    memset(&serun, 0, sizeof(serun));  
    serun.sun_family = AF_UNIX;  
    strcpy(serun.sun_path, server_path);  
    len = offsetof(struct sockaddr_un, sun_path) + strlen(serun.sun_path);  
    if (connect(sockfd, (struct sockaddr *)&serun, len) < 0){  
        perror("connect error");  
        exit(1);  
    }  
 
    while(fgets(buf, MAXLINE, stdin) != NULL) {    
         write(sockfd, buf, strlen(buf));    
         n = read(sockfd, buf, MAXLINE);    
         if ( n < 0 ) {    
            printf("the other side has been closed.
");    
         }else {    
            write(STDOUT_FILENO, buf, n);    
         }    
    }   
    close(sockfd);  
    return 0;  
}  

启动两个client

root@ubuntu:~/c++# ./u_client  /tmp/echo_socket uclient2
helloclient2
Greetings! I am your connection handler
Now type something and i shall repeat wh
at you type 
helloclient2
^C
root@ubuntu:~/c++# ./u_client  /tmp/echo_socket uclient3
helloclient3
Greetings! I am your connection handler
Now type something and i shall repeat wh
at you type 
helloclient3
^C
root@ubuntu:~/c++# 

client 跑在容器中

root@ubuntu:~/c++# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
cb37bad13c9e        debian              "bash"              4 seconds ago       Up 3 seconds                            kind_bartik
fa2d3b3aec76        busybox             "sh"                6 months ago        Up 6 months                             cranky_mendeleev
a9ab3ca9fa95        busybox             "sh"                6 months ago        Up 6 months                             stoic_mcclintock
root@ubuntu:~/c++# docker cp u_client cb37bad13c9e:/
root@ubuntu:~/c++# 
root@ubuntu:~# docker run --runtime runc --rm -ti debian
root@cb37bad13c9e:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  u_client  usr  var
root@cb37bad13c9e:/# ./u_client 
connect error: No such file or directory
root@cb37bad13c9e:/# ls
'HOSTNAME=cb37bad13c9e'   bin   boot   dev   etc   home   lib   media   mnt   opt   proc   root   run   sbin   srv   sys   tmp   u_client   usr   var
root@cb37bad13c9e:/# chmod +x u_client 
root@cb37bad13c9e:/# ./u_client 
connect error: No such file or directory
root@cb37bad13c9e:/# 

root@ubuntu:~/c++# docker search gcc
NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
gcc                                The GNU Compiler Collection is a compiling s…   603                 [OK]                
rikorose/gcc-cmake                 Build on top off the official gcc image incl…   26                                      [OK]
arm32v7/gcc                        The GNU Compiler Collection is a compiling s…   7                                       
arm64v8/gcc                        The GNU Compiler Collection is a compiling s…   6                                       
randomdude/gcc-cross-x86_64-elf    GCC built to target x86_64-elf. Shamelessly …   2                                       [OK]
teeks99/gcc-ubuntu                 Versions of gcc running on ubuntu  The goal …   1                                       [OK]
conanio/gcc5                                                                       1                                       
conanio/gcc7                                                                       1                                       
unikraft/gcc                                                                       1                                       
ppc64le/gcc                        The GNU Compiler Collection is a compiling s…   1                                       
conanio/gcc8                                                                       1                                       
trollin/gcc                                                                        0                                       
rushmash/gcc-arm-embedded-docker   gcc-arm-none-eabi toolchain                     0                                       [OK]
etews/gcc-cmake-python             Gcc with cmake and python based on Debian       0                                       
celiangarcia/gcc6-cmake            Cmake built on top of official gcc 6 image.     0                                       
conanio/gcc9-jnlp-slave                                                            0                                       
s390x/gcc                          The GNU Compiler Collection is a compiling s…   0                                       
phanoix/gcconnex                   :latest image based off alpine                  0                                       [OK]
amd64/gcc                          The GNU Compiler Collection is a compiling s…   0                                       
celiangarcia/gcc8-cmake            Cmake built on top of official gcc 8 image.     0                                       
vcatechnology/gcc5-armv7hf         Specialization of conanio/gcc5-armv7hf          0                                       
conanio/gcc9                                                                       0                                       
arm32v5/gcc                        The GNU Compiler Collection is a compiling s…   0                                       
celiangarcia/gcc7-cmake            Cmake built on top of official gcc 7 image.     0                                       
microblinkdev/gcc-devenv           GCC-based development environment               0                                       
root@ubuntu:~/c++# 
root@ubuntu:~# docker run --runtime runc --rm -ti  arm64v8/gcc 
Unable to find image 'arm64v8/gcc:latest' locally
latest: Pulling from arm64v8/gcc
d62e7e7f9965: Pulling fs layer 
8ba77e956dd9: Pulling fs layer 
02d06261b657: Pulling fs layer 
a74967d868a7: Waiting 
dbf0f9cf1993: Waiting 

root@ubuntu:~# docker run --runtime runc --rm -ti  gcc 
Unable to find image 'gcc:latest' locally
latest: Pulling from library/gcc
d62e7e7f9965: Pull complete 
8ba77e956dd9: Pull complete 
02d06261b657: Pull complete 
a74967d868a7: Pull complete 
dbf0f9cf1993: Pull complete 
56e9a718d723: Pull complete 
5cef519312bd: Pull complete 
fb215d03a23c: Pull complete 
6465a55565b6: Pull complete 
Digest: sha256:3f8b39b5a9e8f03e1bb00ae166f9350fb0fe4413076a697fff9fd8355d13c0ea
Status: Downloaded newer image for gcc:latest
root@1010b7db727a:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@1010b7db727a:/# gcc version
/usr/bin/ld: cannot find version: No such file or directory
collect2: error: ld returned 1 exit status
root@1010b7db727a:/# gcc --version
gcc (GCC) 11.1.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@1010b7db727a:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  u_client.c  usr  var
root@1010b7db727a:/# gcc u_client.c  -o u_client
root@1010b7db727a:/# ./u_client 
connect error: No such file or directory
root@1010b7db727a:/# exit
exit

采用mount bind

root@ubuntu:~# docker run --runtime runc --mount type=bind,src=/tmp/echo_socket,dst=/tmp/echo_socket  --rm -ti  gcc 
root@bf56307e7da3:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  u_client.c  usr  var
root@bf56307e7da3:/# gcc u_client.c  -o u_client
root@bf56307e7da3:/# ./u_client /tmp/echo_socket  client.socket

Greetings! I am your connection handler
Now type something and i shall repeat wh
at you type 

hello

googd
hello
docker
googd
run in docker
docker

server 端 in host

原文地址:https://www.cnblogs.com/dream397/p/14812059.html