• 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

  • 相关阅读:
    有向图的强连通分量——tarjan
    最小生成树——Kruskal算法
    最小生成树——Prim算法
    递归的正确切入方法
    大整数类概述
    初涉算法——STL初步
    初涉算法——C++
    ACM常用模板
    ACM入门步骤(一)
    划分树
  • 原文地址:https://www.cnblogs.com/dream397/p/14812059.html
Copyright © 2020-2023  润新知