unix域套接字

2023-11-08

UNIX域套接字被用来和同一机器上运行的进程通信。尽管因特网域套接字可以用作同样的目的,然而UNIX域套接字更高效。UNIX域套接字只拷贝 数据;它们没有要执行的协议处理,没有要增加或删除的网络头,没有要计算的校验和,没有要产生的序列号,没有要发送的确认信息。


UNIX域 套接字同时提供了流和数据报接口。尽管如此,UNIX域数据报服务是可靠的。消息不会被丢失也不会乱序。UNIX域套接字像在套接字和管道之间的过渡。你 可以使用面向网络的套接字接口来使用它们,或者你可以使用socketpair函数然创建一对没有名字的、连接的UNIX域套接字。



  1. #include <sys/socket.h>

  2. int socketpair(int domain, int type, int protocol, int sockfd[2]);

  3. 成功返回0,错误返回-1。


尽管接口是充分通用的,允许socketpair在任何域里使用,但是操作系统典型地只提供对UNIX域的支持。

下面的代码展示了前面17.2节里的s_pipe函数的基于套接字的版本。这个函数创建了一对已连接的UNIX域流套接字。



  1. #include <sys/socket.h>

  2. /*
  3.  * Returns a full-duplex "stream" pipe (a UNIX domain socket)
  4.  * with the two file descriptors returned in fd[0] and fd[1].
  5.  */
  6. int
  7. s_pipe(int fd[2])
  8. {
  9.     return(socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
  10. }


 一些基于BSD的系统使用UNIX域套接字来实现管道。但是当pipe被调用时,第一个描述符的写端和第二个描述符的读端都被关闭。为了得到一个全双工的管道,我们需要直接调用socketpair。

17.3.1 命名UNIX域套接字(Naming UNIX Domain Sockets)


尽管socketpair函数创建了和对方相连的套接字,但是这个套接字没有名字。这意味着它们不能被无关进程寻址。


在16.3.4节,我们学到了如何把一个地址绑定到一个因特网域套接字上。正如因特网域套接字一样,UNIX域套接字可以被命令并用来宣传服务。然而,UNIX域使用的地址格式和因特网域套接字不同。


回想下16.3节套接字地址格式在不同的实现上都会有所区别。一个UNIX域套接字的地址由一个sockaddr_un结构体表示。在Linux2.4.22和Solaris 9上,sockaddr_un结构全被定义在头文件里,如下:


struct sockaddr_un {
  sa_family_t  sun_family;  /* AF_UNIX */
  char sun_path[108];  /* pathname */
};


然而,在FreeBSD 5.2.1和Mac OS X10.3上,sockaddr_un结构体被定义为:


struct sockaddr_un {
  unsigned char  sun_len;  /* length including null */
  sa_family_t  sun_family;  /* AF_UNIX */
  char  sun_path[104];  /* pathname */
};


sockaddr_un的结构体sun_path成员包含一个路径名。当我们把一个地址绑定到一个UNIX域套接字时,系统用相同的名字创建一个类型为S_IFSOCK的文件。


这个文件的存在只做为对客户宣传套接字名的一种方式。这个文件不能被打开或被应用为通信的其它使用。


当我们尝试绑定到相同的地址时如果文件已经存在,bind请求将会失败。当我们关闭套接字时,这个文件会自动被删除,所以我们在程序退出时需要确保我们反链接了它。


下面的程序展示了绑定一个地址到一个UNIX域套接字的一个例子。



  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <stddef.h>

  4. int
  5. main(void)
  6. {
  7.     int fd, size;
  8.     struct sockaddr_un un;

  9.     un.sun_family = AF_UNIX;
  10.     strcpy(un.sun_path, "foo.socket");
  11.     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
  12.         printf("socket failed\n");
  13.         exit(1);
  14.     }
  15.     size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
  16.     if (bind(fd, (struct sockaddr *)&un, size) < 0) {
  17.         printf("bind failed\n");
  18.         exit(1);
  19.     }
  20.     printf("UNIX domain socket bound\n");
  21.     exit(0);
  22. }

当我们运行这个程序时,bind请求成功,但是如果我们第二次运行这个程序时,我们得到一个错误,因为文件已经存在。直到我们删除这个文件,程序会再次成功。 $ ./a.out UNIX domain socket bound $ ls -l foo.socket srwxrwxr-x 1 tommy tommy 0 2012-03-24 17:11 foo.socket $ ./a.out bind failed $ rm foo.socket $ ./a.out UNIX domain socket bound 

我们确定要绑定的地址的尺寸的方法是确定sun_path成员在sockaddr_un结构体里的偏移量并加上路径名的长度,不包含 终止空字符。因为在sockaddr_un结构体里在sun_path之前的成员会随着实现而改变,所以我们使用 里的 offsetof宏来计算sun_path成员从结构体开始的偏移量。如果你进入 ,你将看到类似于如下的定义:

#define offsetof(TYPE, MEMBER)  ((int)&((TYPE *)0)->MEMBER)

这个表达式得到一个整型,它是成员的起始地址,假定结构体起始于0。

17.3.2 唯一连接(Unique Connections)


一个服务器可以使用bind、listen和accept函数来安排唯一的到客户的UNIX域连接。客户使用connect来联系服务器;在连接请求被服务器接受后,在客户和服务器之间有唯一的连接。这种操作风格和我们在16.5节里演示的因特网域套接字相同。


下面的代码展示了serv_listen函数的UNIX域套接字版本。



  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <errno.h>
  4. #include <stddef.h>

  5. #define QLEN 10

  6. /*
  7.  * Create a server endpoint of a connection.
  8.  * Return fd if all OK, <on error.
  9.  */
  10. int
  11. serv_listen(const char *name)
  12. {
  13.     int fd, len, err, rval;
  14.     struct sockaddr_un un;

  15.     /* creat a UNIX domain stream socket */
  16.     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  17.         return(-1);

  18.     unlink(name); /* in case it already exists */

  19.     /* fill in socket address structure */
  20.     memset(&un, 0, sizeof(un));
  21.     un.sun_family = AF_UNIX;
  22.     strcpy(un.sun_path, name);
  23.     len = offsetof(struct sockaddr_un, sun_path) + strlen(name);

  24.     /* bind the name to the descriptor */
  25.     if (bind(fd, (struct sockaddr *)&un, len) < 0) {
  26.         rval = -2;
  27.         goto errout;
  28.     }

  29.     if (listen(fd, QLEN) < 0) { /* tell kernel we're a server */
  30.         rval = -3;
  31.         goto errout;
  32.     }
  33.     return(fd);

  34. errout:
  35.     err = errno;
  36.     close(fd);
  37.     errno = err;
  38.     return(rval);
  39. }


首先,我们通过调用socket创建单个UNIX域套接字。我们然后填充一个sockaddr_un结构体,把熟知的路径名赋 到这个套接字上。这个结构体是bind的参数。注意我们不需要设置在一些平台上出现的sun_len域,因为操作系统使用我们传给bind函数的地址长度 为我们设置了这个。


最后,我们调用listen(16.4节)来告诉内核进程将扮演一个服务器,等待客户的连接。当一个客户的一个连接请求到达时,服务器调用serv_accept函数(下面的代码)。



  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <time.h>
  4. #include <errno.h>
  5. #include <fcntl.h>
  6. #include <stddef.h>

  7. #define STALE 30 /* client's name can't be older than this (sec) */

  8. /*
  9.  * Wait for a client connection to arrive, and accept it.
  10.  * We also obtain the client's user ID from the pathname
  11.  * that it must bind before calling us.
  12.  * Returns new fd if all OK, <on error
  13.  */
  14. int
  15. serv_accept(int listenfd, uid_t *uidptr)
  16. {
  17.     int clifd, len, err, rval;
  18.     time_t staletime;
  19.     struct sockaddr_un un;
  20.     struct stat statbuf;

  21.     len = sizeof(un);
  22.     if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
  23.         return(-1); /* often errno=EINTR, if signal caught */

  24.     /* obtain the client's uid from its calling address */
  25.     len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
  26.     un.sun_path[len] = 0; /* null terminate */

  27.     if (stat(un.sun_path, &statbuf) < 0) {
  28.         rval = -2;
  29.         goto errout;
  30.     }
  31. #ifdef S_ISSOCK /* not defined for SVR4 */
  32.     if (S_ISSOCK(statbuf.st_mode) == 0) {
  33.         rval = -3; /* not a socket */
  34.         goto errout;
  35.     }
  36. #endif
  37.     if ((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||
  38.             (statbuf.st_mode & S_IRWXU) != S_IRWXU) {
  39.         rval = -4; /* is not rwx------ */
  40.         goto errout;
  41.     } 

  42.     staletime = time(NULL) - STALE;
  43.     if (statbuf.st_atime < staletime ||
  44.             statbuf.st_ctime < staletime ||
  45.             statbuf.st_mtime < staletime) {
  46.         rval = -5; /* i-node is too old */
  47.         goto errout;
  48.     }

  49.     if (uidptr != NULL)
  50.         *uidptr = statbuf.st_uid; /* return uid of caller */
  51.     unlink(un.sun_path); /* we're done with pathname now */
  52.     return(clifd);

  53. errout:
  54.     err = errno;
  55.     close(clifd);
  56.     errno = err;
  57.     return(rval);
  58. }

服务器阻塞在accept的调用里,等待一个客户调用cli_conn。当accept返回时,它的返回值是一个和客户连接的全新的描 述符。(这和connld模块在STREAMS子系统上做的事有些相似。)此外,客户赋到它套接字上的路径名(包含客户进程ID的那个名字)被由 accept返回,通过第二个参数(指向sockaddr_un结构体的指针)。我们使路径名空字符终止并调用stat。这让我们验证路径名确实是一个套 接字且和这个套接字相关的三个时间都不老于30秒。(回想6.10节time函数返回自Epoch至今的秒数。)


如果三个检查都成功,那么我们假定客户的标识(它的用效用户ID)是套接字的属主。尽管这个检查并不完美,但是它是在当前系统上我们能做的最好的了。(如果内核返回有效用户ID给accept,就像I_RECVFD ioctl命令做的那样,那就更好了。)


客户通过调用cli_conn函数来初始化到服务器的连接。如下面的代码所示。



  1. #include <sys/socket.h>
  2. #include <sys/un.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <stddef.h>

  6. #define CLI_PATH "/var/tmp" /* +for pid = 14 chars */
  7. #define CLI_PERM S_IRWXU /* rwx for user only */

  8. /*
  9.   * Create a client endpoint and connect to a server.
  10.   * Returns fd if all OK, <on error.
  11.   */
  12. int
  13. cli_conn(const char *name)
  14. {
  15.     int fd, len, err, rval;
  16.     struct sockaddr_un un;

  17.     /* create a UNIX domain stream socket */
  18.     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  19.         return(-1);

  20.     /* fill socket address structure with our address */
  21.     memset(&un, 0, sizeof(un));
  22.     un.sun_family = AF_UNIX;
  23.     sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
  24.     len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);

  25.     unlink(un.sun_path); /* in case it already exists */
  26.     if (bind(fd, (struct sockaddr *)&un, len) < 0) {
  27.         rval = -2;
  28.         goto errout;
  29.     }
  30.     if (chmod(un.sun_path, CLI_PERM) < 0) {
  31.         rval = -3;
  32.         goto errout;
  33.     }
  34.     /* fill socket address structure with server's address */
  35.     memset(&un, 0, sizeof(un));
  36.     un.sun_family = AF_UNIX;
  37.     strcpy(un.sun_path, name);
  38.     len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
  39.     if (connect(fd, (struct sockaddr *)&un, len) < 0) {
  40.         rval = -4;
  41.         goto errout;
  42.     }
  43.     return(fd);

  44. errout:
  45.     err = errno;
  46.     close(fd);
  47.     errno = err;
  48.     return(rval);
  49. }

我们调用socket来创建一个UNIX域套接字的客户的那端。我们然后用客户相关的名字来填充sockaddr_un结构体。

我们不让系统选择一个默认的地址,因为服务器会不能把一个客户和另一个区分开。事实上,我们绑定自己的地址,一个当开发使用套接字的客户程序时通常不会采取的步骤。


我 们绑定的路径名的最后最后五个字符由客户的进程ID组成。我们调用unlink,只是防止路径名已经存在。我们然后调用bind来给客户的套接字赋一个名 字。这在文件系统里用和被绑定的路径路径名相同的名字创建一个套接字文件。我们调用chmod来关闭除了用户读、用户写和用户执行之外的所有权限。在 serv_accept里,服务器检查这些权限和套接字的用户ID来检查客户的身份。


我们然后必须填充另一个sockaddr_un结构体,这将是服务器的被熟知的路径名。最后,我们调用connect函数来初始化和服务器的连接。

附上自己练习的代码:

server:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/un.h>


#define SOCK_ADDR "/home/yzh/usocket_test/socket"

int main(int argc,char *argv[])
{
        int listenfd,conn_id;
        struct sockaddr_un un;
        char wbuffer[1024] = {0};
        char rbuffer[1024] = {0};
        unlink(SOCK_ADDR);
        if((listenfd = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
                printf("socket create error!\n");
                exit(0);
        }
        memset(&un,0,sizeof(un));
        un.sun_family = AF_UNIX;
        strcpy(un.sun_path,SOCK_ADDR);
        if(bind(listenfd,(struct sockaddr *)&un,sizeof(un)) < 0){
                printf("bind error!\n");
                exit(0);
        }
        if(listen(listenfd,SOMAXCONN) < 0){
                printf("listen error!\n");
                exit(0);
        }
        while(1){
                printf("accept cli!\n");
                if((conn_id = accept(listenfd,NULL,NULL)) < 0){
                        printf("connect fail!\n");
                }
                printf("write : hi i am yzh!\n");
                strcpy(wbuffer,"hi i am yzh!");
                write(conn_id,wbuffer,sizeof(wbuffer));
                read(conn_id,rbuffer,1024);
                printf("read : %s \n ",rbuffer);
        }
        return 0;
}

编译:

gcc server.c -o server


client:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/un.h>


#define SOCK_ADDR "/home/yzh/usocket_test/socket"

int main(int argc,char * argv[])
{
        int sock_id;
        struct sockaddr_un un;
        char rbuffer[1024] = {0};
        char wbuffer[1024] = {0};
        if((sock_id = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
                printf("create unix socket fail!\n");
                exit(0);
        }
        printf("create unix socket success!\n");
        un.sun_family = AF_UNIX;
        strcpy(un.sun_path,SOCK_ADDR);
        if(connect(sock_id,(struct sockaddr *)&un,sizeof(un)) < 0){
                printf("connect fail!\n");
                exit(0);
        }
        read(sock_id,rbuffer,1024);
        sleep(3);
        strcpy(wbuffer,"welcom~");
        write(sock_id,wbuffer,sizeof(wbuffer));
        printf("read : %s \n",rbuffer);
        close(sock_id);
        return 0;
}

编译:

gcc client.c -o cli


运行:

./server会在SOCK_ADDR所在的目录下生成一个名为socket(名字可以自己定)的文件。

再打开一个终端运行:./cli

运行结果:

终端1:

yzh@yzh-Latitude-E5440:~/usocket_test$ ./server 
accept cli!
write : hi i am yzh!
read : welcom~ 

终端2:

yzh@yzh-Latitude-E5440:~/usocket_test$ ./cli 
create unix socket success!
read : hi i am yzh! 

yzh@yzh-Latitude-E5440:~/usocket_test$

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

unix域套接字 的相关文章

  • 如何在 ruby​​ 中后台运行多个外部命令

    给定这个 Unix shell 脚本 test sh bin sh sleep 2 sleep 5 sleep 1 wait 时间 test sh real 0m5 008s user 0m0 040s sys 0m0 000s 如何在 U
  • unix 命令行执行方式为 . (点)与没有

    在 unix 命令行中 通过简单地键入程序名称来执行程序与通过键入 点 后跟程序名称 例如 runme vs runme name来源称为文件name进入当前外壳 所以如果一个文件包含这个 A hello 然后 如果您获取它 之后您可以引用
  • 使用 sh shell 比较字符串

    我正在使用 SH shell 我试图将字符串与变量的值进行比较 但是if条件始终执行为真 为什么 这是一些代码 Sourcesystem ABC if Sourcesystem eq XYZ then echo Sourcesystem M
  • Unix cURL POST 使用文件中的内容到特定变量

    我已经搜索过这个答案 但没有找到任何有效或完全符合我的问题的答案 使用 Unix cURL 我需要将键 值对发布到服务器 密钥将是 MACs 换行符分隔的 MAC 地址文件的内容将是此 POST 的 VALUE 我试过了 curl d fi
  • 模拟用户输入以使用不同参数多次调用脚本

    我必须使用提供的脚本 该脚本在脚本运行时接受用户输入而不是参数 我无法解决这个问题 脚本的一个例子是 bin bash echo param one read one doSomething echo param two read two
  • 如何拆分一行并重新排列其元素?

    我在一行中有一些数据 如下所示 abc edf xyz rfg yeg udh 我想呈现如下数据 abc xyz yeg edf rfg udh 以便打印备用字段并用换行符分隔 有没有这样的衬里 下列awk脚本可以做到这一点 gt echo
  • Supervisorctl 错误:unix:///var/run/supervisord.sock 拒绝连接? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这是我的配置文件 我运行supervisord c etc supervisor supervisord conf效果很好 当我尝试跑步时
  • 使用Sed查找并替换json字段

    我有一组 json 文件 其中在最后一个键值对之后有需要替换的逗号 RepetitionTime 0 72 TaskName WM Manufacturer Siemens ManufacturerModelName Skyra Magne
  • 如何在Unix中将相对路径转换为绝对路径[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想转换 相对路径 home stevin data APP SERVICE datafile txt to 绝对路径 home stev
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • 在C语言中如何清屏? [复制]

    这个问题在这里已经有答案了 我想清除屏幕上的所有文字 我尝试过使用 include
  • 在 Unix 中添加用户和组

    有谁知道在unix中添加用户和组以及删除它们的api吗 我想以编程方式执行此操作 谢谢 坦率 我开始查看一些系统调用并发现以下内容 请注意 它们具有不同的标准 因此并非所有标准都可以在您的 Unix 版本上运行 getpwent setpw
  • SCP 权限被拒绝(公钥)。仅当在目录上使用 -r 标志时才在 EC2 上

    scp r Applications XAMPP htdocs keypairfile pem uploads ec2 user publicdns var www html 其中 uploads 是目录 返回权限被拒绝 公钥 Howeve
  • 使用带有curl 的内部字段分隔符

    当我做 ls IFS l 我得到了我期望的输出 当我做 curl IFShttp www google com 我不 我是否误解了内部字段分隔符 如何在不使用任何空格字符的情况下运行curl 命令 您需要将变量放在大括号内 否则 shell
  • Python 中的 Unix cat 函数 (cat * > merged.txt)? [复制]

    这个问题在这里已经有答案了 一旦建立了目录 有没有办法在Python中使用Unix中的cat函数或类似的函数 我想将 files 1 3 合并到 merged txt 我通常会在 Unix 中找到该目录 然后运行 cat gt merged
  • 如何在 shell 脚本中操作 $PATH 元素?

    有没有一种惯用的方法从类似 PATH 的 shell 变量中删除元素 这就是我想要的 PATH home joe bin usr local bin usr bin bin path to app bin and remove or rep
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • awk/Unix 分组依据

    有这个文本文件 name age joe 42 jim 20 bob 15 mike 24 mike 15 mike 54 bob 21 试图得到这个 计数 joe 1 jim 1 bob 2 mike 3 Thanks awk F NR
  • ssh远程变量赋值?

    以下内容对我不起作用 ssh email protected cdn cgi l email protection k 5 echo k 它只是返回一个空行 如何在远程会话 ssh 上分配变量 Note 我的问题是not关于如何将本地变量传

随机推荐

  • PTA 基础编程题目集 7-20 打印九九口诀表 C语言

    PTA 基础编程题目集 7 20 打印九九口诀表 C语言 下面是一个完整的下三角九九口诀表 本题要求对任意给定的一位正整数N 输出从11到NN的部分口诀表 输入格式 输入在一行中给出一个正整数N 1 N 9 输出格式 输出下三角N N部分口
  • ❤️【数据结构】之单链表的增、删、查、改(C语言实现)看一遍就会!!!

    文章目录 前言 作者简介 一 单链表 二 1 单链表结构 2 创建新节点 3 单链表的头插 2 单链表的尾插 3 单链表的头删 4 单链表的尾删 5 找到某个值的位置 6 在任意值前面插入值 7 删除任意位置的值 8 打印链表 9 主函数
  • Elasticsearch基本操作

    1 数据格式 Elasticsearch是面向文档型数据库 一条数据在这里就是一个文档 为了方便理解 我们将Elasticsearch里存储文档数据和关系型数据库MySQL存储数据的概念进行类比 这里 Types 的概念已经被逐渐弱化 El
  • 联机手写汉字识别,基于新型RNN网络结构的方法

    本文简要介绍2019年4月Pattern Recognition录用论文 RecognizingOnline Handwritten Chinese Characters Using RNNs with New Computing Arch
  • Unity的Input.GetAxis()的返回值

    Unity的Input GetAxis float moveHorizontal Input GetAxis Horizontal 水平的向左是 1 向右是1 静止返回值是0 float moveVertical Input GetAxis
  • 使用boost::range模块进行反转操作的相关测试程序

    使用boost range模块进行反转操作的相关测试程序 在C 中 使用第三方库可以帮助我们更方便地进行各种操作 boost库是一个受欢迎的C 库之一 提供了许多功能强大的模块 其中 boost range模块为我们提供了一组用于操作范围的
  • 一线大厂的企业云原生成本优化实践指南

    胡忠想 星汉未来联合创始人 CPO 读完需要 18分钟 速读仅需 6 分钟 1 前言 近年来 公有云 混合云等技术在全球迅速发展 云的普及度越来越高 Docker Kubernetes DevOps Service Mesh 等云原生技术蓬
  • 软件测试常见面试题

    文章目录 1 你的测试职业发展是什么 2 你认为测试人员需要具备哪些素质 3 你为什么能够做测试这一行 4 测试的目的是什么 5 测试分为哪几个阶段 6 单元测试的测试对象 目的 测试依据 测试方法 7 怎样看待加班问题 8 结合你以前的学
  • 【Python数据科学手册】Pandas——二、Pandas对象简介

    文章目录 二 Pandas对象简介 1 Pandas的Series对象 1 Serise是通用的NumPy数组 2 Series是特殊的字典 3 创建Series对象 2 Pandas的DataFrame对象 1 DataFrame是通用的
  • Spring Oauth2-Authorization-Server jwt 认证

    Spring Oauth2 Authorization Server jwt 认证机制 基于 spring security oauth2 authorization server 0 2 3 配置 资源服务器配置 Bean Securit
  • 全鲸董事长韩耀宁受邀出席第十九届中国科学家论坛,发表重要演讲

    9月18日 第十九届中国科学家 国际 论坛在京隆重开幕 来自全国各地行业的院士 科学家 教授 学者 科技工作者以及2000多名各行业领军企业家出席了本次年度盛会 大会以 推动科技国际合作 提高我国科技创新国际影响力 塑造创新发展新优势 为主
  • 用递归算法实现开平方根

    用递归算法实现开平方根 前言 本文是用手算平方根的解法 用python代码实现 手算平方根方法学自西瓜视频李永乐老师 代码为个人原创 手算平方根方法 现在我们有一个非负数S 要求S的平方根 我们可以先将S拆成两个数相加 这两个数分别是小于等
  • Filter过滤器——javaweb

    介绍 Filter 过滤器 用来过滤网站数据 每次请求都会走一次过滤器 直到服务器关闭 Filter 实现步骤 导包
  • QT界面:控件随界面大小自适应变化

    在用QT做一个图像显示界面的过程中需要控件随着QT界面缩放进行自适应变化的问题 特此记录一下 环境 Win10 VS2015 QT5 1 拖拽控件 首先 新建一个QT GUI工程 在Qt Designer中调整界面大小并拖拽需要的控件 如图
  • Vue---Vue常用特性

    一 常用特性概览 表单操作 自定义指令 计算属性 过滤器 侦听器 声明周期 1 表单操作 2 表单域修饰符 number 转化为数值 trim 去掉开始和结尾空格 lazy 将input事件切换change事件
  • el-upload+额外的参数 , element上传功能组件及其参数的详解

    前言 我们使用 element ui 的时候 可能会有一个需求要给后台传入额外的值 我这边是遇到了 然后通过找到各种资料解决了 现在把我的upload的组件分享一下 可以实现导入 导出功能 导入的时候也会有额外的参数 这个是通过 gjlx
  • C++11:右值引用

    新特性目的 右值引用 Rvalue Referene 是 C 新标准 C 11 11 代表 2011 年 中引入的新特性 它实现了转移语义 Move Sementics 和精确传递 Perfect Forwarding 它的主要目的有两个方
  • 【论文阅读】Three scenarios for continual learning

    文章目录 题目 2019 Three scenarios for continual learning 1 论文的总体介绍 2 论文提出的 benchmark 三种场景 2 1 三种场景的定义如下 2 2 split task protoc
  • 动态个人导航网HTML单页源码

    一款单页的网址发布页单页 HTML 模板 可用于网址发布页使用 本模板简约商务 页面精美没有花里胡哨的效果 喜欢的敬请使用 右键单击直接就可以单页面修改 直接下载就可以使用啦 源码地址 旭音导航网 zip 蓝奏云
  • unix域套接字

    UNIX域套接字被用来和同一机器上运行的进程通信 尽管因特网域套接字可以用作同样的目的 然而UNIX域套接字更高效 UNIX域套接字只拷贝 数据 它们没有要执行的协议处理 没有要增加或删除的网络头 没有要计算的校验和 没有要产生的序列号 没