读书笔记_《Linux高性能服务器编程》_第 5 章:网络编程基础API

2023-11-12

第 5 章 Linux网络编程基础API

知识要点:

  • socket 地址 API
  • socket 基础 API
  • 网络信息 API

1、socket 地址API

主机字节序和网络字节序

CPU (32位)的累加器一次至少可以装载 4 字节,即一个整数。该 4 字节在内存中的排列顺序将影响其被累加器装载成的整数的值 => 字节序问题。

大端字节序(网络字节序): 数据的高字节数据存储在内存的低地址处。当数据在使用不同字节序的机器间传递数据时,对于数据的解析将会出错,因此,规定在发送端总是将数据转化为大端字节序数据后再进行发送,接收端知道数据总是大端字节序,则根据自身本机采用的字节序决定是否需要转化,确定了数据收发的正确性。

小端字节序(主机字节序): 数据的低字节数据存储在内存的低地址处。一般的 PC 都是采用小端字节序,因此又称主机字节序。

通用 socket 地址

#include <bits/socket.h>
struct sockaddr
{
    //地址族变量 与协议族类型对应
    sa_family_t sa_family;
    //存放 socket 地址值
    //不同的协议的含义和长度不同,后续针对具体协议专用的结构体
    char sa_data[14];
};

常见协议族(protocol family,也称 domin)与对应地址族如下图,两者具有相同的值,可以混用。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uLSC5UEN-1623659442704)(./Pic/table-5-1.png)]

sa_data 成员存放的 socket 地址值 对应关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cca5W0EI-1623659442709)(./Pic/table-5-2.png)]

14 字节的 sa_data 成员无法容纳多数协议族的地址值,提出新的通用 socket 地址结构体

#include <bits/socket.h>
struct sockaddr_storage
{
    sa_family_t sa_family;
    unsigned long int __ss_align;
    char __ss_padding[128 - sizeof(__ss_align)];
};
///提供更大空间存储地址值,且内存对齐(__ss_align作用)

专用 socket 地址

Linux 为各协议族提供专门的 socket 地址结构体,方便设置与获取 IP 地址和端口。

Unix:

#include <sys/un.h>
struct sockaddr_un
{
    sa_family_t sa_family;//地址族:AF_UNIX
    char sun_path[108];//文件路径名
};

IPV4:

struct in_addr
{
    u_int32_t s_addr;//IPV4地址,网络字节序表示
};

struct sockaddr_in
{
    sa_family_t sin_family;//地址族:AF_INET
    u_int16_t sin_port;//端口号,网络字节序表示
    struct in_addr sin_addr;//IPV4地址结构体
};

IPV6:

struct in6_addr
{
    unsigned char sa_addr[16];//IPV6地址,网络字节序表示
};

struct sockaddr_in
{
    sa_family_t sin6_family;//地址族:AF_INET6
    u_int16_t sin6_port;//端口号,网络字节序表示
    u_int32_t sin6_flowinfo;//流消息,设置为0
    struct in6_addr sin6_addr;//IPV6地址结构体
    u_int32_t sin6_scope_id;//scope ID
};

注意: 所有专用 socket 地址在使用 socket 编程接口时都需要转换成通用 socket 地址(sockaddr 类型)。

IP 地址转换

IPV4:

#include <arpa/inet.h>
//将用点分十进制字符串表示的 IPV4 地址转换成网络字节序整数表示的 IPV4 地址,
//失败返回 INADDR_NONE
in_addr_t inet_addr(const char* strptr);
//与 inet_addr 功能一致,将结果存入 inp 指向的结构体中
//失败返回 0,成功返回 1
int inet_aton(const char* cp, struct in_addr* inp);
//将网络字节序整数表示的 IPV4 地址转化为用点分十进制表示的 IPV4 地址
//内部使用静态变量存储转化结果,返回值指向该静态内存,不可重入
//失败返回 0,成功返回 1
char* inet_ntoa(struct in_addr in);

IPV4 与 IPV6 同时适用:

#include <arpa/inet.h>
//10进制点分字符串的IPV4地址或16进制IPV6地址转换成网络字节序整数的IP地址,并存入dst内存
//af:对应的协议族 AF_INET 或 AF_INET6
//失败返回 0,成功返回 1
int inet_pton(int af, const char* src, void* dst);

//与inet_pton函数相反,socklen_t 指定目标存储单元的大小见后续宏
//成功返回目标存储单元地址,失败返回NULL并设置errno
const char* inet_ntop(int af, const char* src, char* dst, socklen_t cnt);

#include <netinet/in.h>
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46

2、创建 socket

#include <sys/types.h>
#include <sys/socket.h>
/**
	domin:底层协议族 PF_INET/PF_INET6/PF_UNIX
	type:服务类型 SOCK_STREAM/SOCK_DGRAM
	protocol: 具体协议,唯一值,一般设为0表示使用默认协议
	成功返回 socket 文件描述符,失败返回 -1 并置 errno
*/
int socket(int domin, int type, int protocol);

拓展: type值可以和 SOCK_NONBLOCK 及 SOCK_CLOEXEC 标志相与,表示新创建的 socket 为非阻塞,以及 fork 调用创建子进程时在子进程中关闭该socket

3、命名 socket

#include <sys/types.h>
#include <sys/socket.h>
/**
	fd: 需要命名的socket的文件描述符
	myaddr: 分配的 socket 地址
	addrlen: sizeof(myaddr)
	成功返回0,失败返回 -1 置 errno
	EACCESS: 被绑定的地址是受保护的地址,仅超级用户能够访问,如:绑定到知名服务端口(0~1023)
	EADDRINUSE: 被绑定的地址正在使用,如:处于TIME_WAIT状态的 socket 地址
*/
int bind(int fd, const struct sockaddr* myaddr, socklen_t addrlen);

4、监听 socket

socket 被命名后,需要调用系统调用来创建一个监听队列存放待处理的客户连接。

#include <sys/socket.h>
/**
	sockfd: 被监听的 socket
	backlog: 监听队列中处于ESTABLISED状态的最大值,当超过时服务器不再受理新的客户连接,客户	端收到 ECONNREFUSED 错误信息(但实际值往往可能为backlog+1)
	成功返回0,失败返回 -1 置 errno
*/
int listen(int sockfd, int backlog);

5、接受连接

#include <sys/types.h>
#include <sys/socket.h>
/**
	sockfd: listen系统调用的监听socket
	addr: 获取接受连接的远程socket地址
	addrlen: socket长度
	成功返回0,失败返回 -1 置 errno
*/
int accept(int sockfd,struct sockaddr* addr, socklen_t* addrlen);

//accept只是从监听队列中取出连接,而不论连接处于何种状态(如CLOSE_WAIT),更不关心网络状况的变化

6、发起连接

客户端主动的发起连接,服务端被动的接受连接。

#include <sys/types.h>
#include <sys/socket.h>
/**
	sockfd: 创建socket返回的文件描述符,通过读取该sockfd来与服务端进行通信
	serv_addr: 需要连接的服务端socket地址
	addrlen: socket地址长度
	成功返回0,失败返回 -1 置 errno
*/
int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t* addrlen);

ECONNREFUSED: 目标端口不存在,连接被拒绝
ETIMEDOUT:连接超时

7、关闭连接

#include <unistd.h>
/**
	并非是立刻关闭一个连接,而是将fd的引用计数减1,当fd的引用计数为0才真正关闭连接
	多进程时,一次fork默认会将父进程打开的socket的引用加1,必须在父子进程中都对该socket执行	close调用才能将连接关闭。
*/
int close(int fd);

立即终止连接!

#include <sys/socket.h>
/**
	成功返回0,失败返回 -1 置 errno
*/
int shutdown(int sockfd, int howto);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mmLxOTnN-1623659442711)(./Pic/table-5-3.png)]

8、数据读写

TCP 数据读写

#include <sys/types.h>
#include <sys/socket.h>
/**
	sockfd: 从sockfd读取、往sockfd写入
	buf: 读/写缓冲区
	len: 缓冲区长度
	flags: 额外控制的标志
*/

//成功返回实际读取到的长度,可能小于期望值len则可以多次调用读取完整
//返回0时,以为通信对方已经关闭连接
//失败返回 -1 置 errno
ssize_t recv(int sockfd, void* buf, size_t len, int flags);
//成功返回实际写入的长度,失败返回 -1 置 errno
ssize_t send(int sockfd, const void* buf, size_t len, int flags);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BnO3HIFk-1623659442717)(./Pic/table-5-4.png)]

send 与 recv 设置的flags是一次性的,可以通过 setsockopt 系统调用永久性的修改 socket 某些属性。

UDP 数据读写

#include <sys/types.h>
#include <sys/socket.h>
/**
	UDP协议不是面向连接的,
	接收时都要记录发送方的地址和端口
	发送时需要指明发送给哪个地址和端口
	返回值与send/recv一致,TCP使用该接口时可以把最后两个参数置为 NULL
*/
ssize_t recvfrom(int sockfd, void* buf, size_t len, int flags, struct sockaddr_in* src_addr, socklen_t* addrlen);
ssize_t sendto(int sockfd, const void* buf, size_t len, int flags, struct sockaddr_in* dest_addr, socklen_t* addrlen);

通用数据读写函数

socket 编程接口提供即支持 TCP 又支持 UDP 的读写系统调用。

#include <sys/socket.h>

struct iovec
{
    void* iov_base;//内存起始地址
    size_t iov_len;//内存的长度
};

struct msghdr
{
    //socket地址,指向 socket 地址结构变量,指定通信对方socket地址,对于TCP无用置为NULL
    void* msg_name;
    //socket地址的长度
    socklen_t msg_namelen;
    //分散的内存块
    struct iovec* msg_iov;
    //分散内存块的数量
    int msg_iovlen;
    //指向辅助数据的起始位置
    void* msg_control;
    //辅助数据的大小
    socklen_t msg_controllen;
    //复制函数中flags参数,在调用过程中更新
    int msg_flags;
};

//返回值与send/recv一致
ssize_t recvmsg(int sockfd, struct msghdr* msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr* msg, int flags);

分散读: 对于recvmsg读取的数据将存放在msg_iovlen块分散的内存中,内存的地址及长度由msg_iov指向的数组决定

集中写: 对于sendmsg而言,msg_iovlen块分散内存中的数据将一并发送

9、带外数据

Linux 内核检测到 TCP 紧急标志时,将会通过 IO 复用产生的异常事件和 SIGURG 信号 来通知应用程序有带外数据需要接收。

#include <sys/socket.h>
/**
	判断 sockfd 下一个被读取到的数据是否是带外数据
	是:返回 1 ,否:返回0
*/
int sockatmark(int sockfd);

10、获取地址信息函数

#include <sys/socket.h>
/**
	获取本端连接的socket地址信息存入address,长度存入address_len
	若实际socket地址长度比address所指向的内存区大,则地址将被截断
	成功返回0,失败返回 -1 置 errno
*/
int getsockname(int sockfd, struct sockaddr* address, socklen_t* address_len);
/**
	获取通信连接另一端的socket地址
	参数和返回值含义与getsockname同
*/
int getpeername(int sockfd, struct sockaddr* address, socklen_t* address_len);

11、socket 选项

fcntl 系统调用专门用来控制文件描述符属性,socket 编程接口也提供了设置 socket 文件描述符属性的方法:

#include <sys/socket.h>
int getsockopt(int sockfd,//指定被操作的 目标socket
               int level,//指定操作哪个协议的属性
               int option_name,//选项的名字
               void* option_value,//被操作选项的值
               socklen_t* restrict option_len//被操作选项的长度         
              );

int setsockopt(int sockfd, int level, int option_name, const
               void* option_value, socklen_t* option_len);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCv2cjpH-1623659442721)(./Pic/table-5-5.png)]

注意: 对于服务端而言, listen 之后,accept 从监听队列中返回的连接至少完成了 TCP 三次握手的前两阶段即进入 SYN_RECVD 状态,通信双方的同步报文段都已经发送给对方,而有些属性如:TCP最大报文段,则只能由同步报文段来发送,所以需要在 listen 之前设置属性;对于客户端则需要在 connect 之前设置属性。

对 listen 之前设置的属性,accept 返回的连接将自动继承:SO_DEBUG、SO_DONTROUTE、SO_ KEEPALIVE、SO_ LINGER、 SO_ OOBINLINE、SO RCVBUF、SO_RCVLOWAT、SO SNDBUF、SO SNDLOWAT、TCP_ MAXSEG 和 TCP_ NODELAY

11、网络信息 API

gethostbyname 和 gethostbyaddr

gethostbyname 通过主机名称获取主机的完整信息,函数通常先在本地的 /etc/hosts 配置文件中查找主机,如果没有找到再去访问 DNS 服务器。

gethostbyaddr 通过地址名获取主机的完整信息。

#include <netdb.h>

struct hostent
{
	char* h_name;//主机名
	char** h_aliases;//主机别名列表
	int h_addrtype;//地址族类型
	int h_length;//地址长度
	char** h_addr_list;//网络字节序列出的主机IP地址列表
};

/**
	name: 目标主机名称
*/
struct hostent* gethostbyname(const char* name);

/**
	name: 目标主机IP地址
	len: 指定IP地址的长度
	type: AF_INET/AF_INET6
*/
struct hostent* gethostbyaddr(const void* addr, size_t len, int type);

getservbyname 和 getservbyport

通过服务名称获取某个服务的完整信息 及 通过端口获取某个服务的完整信息。

都是通过读取 /etc/services 文件获取服务的信息。

#include <netdb.h>

struct servent
{
    char* s_name;//服务的名称
    char** s_aliases;//服务的别名列表
    int s_port;//服务的端口号
    char* s_proto;//服务类型,tcp或udp
};
/**
	name: 目标服务的名称
	proto: 服务类型,"tcp"表示获取数据流服务,“udp”表示获取数据报服务
*/
struct servent* getservbyname (const char* name, const char* proto);
/**
	name: 目标服务的端口
	proto: 服务类型,"tcp"表示获取数据流服务,“udp”表示获取数据报服务
*/
struct servent* getservbyport (int port, const char* proto);

getaddrinfo

即能通过主机名获取IP地址(内部gethostbyname),也能通过服务名获取端口号(内部getservbyname)

#include <netdb.h>

struct addrinfo
{
    int ai_flags;//取表5-6中标志的按位或
    int ai_family;//地址族
    int ai_socktype;//服务类型,SOCK_STREAM/SOCK_DGRAM
    int ai_protocol;//指具体协议,与socket系统调用一致,一般设为0
    socklen_t ai_addrlen;//ai_addr的长度
    char* ai_canonname;//主机的别名
    struct sockaddr* ai_addr;//指向socket地址
    struct addrinfo* ai_next;//指向下一个sockinfo结构的对象
};

int getaddrinfo(
    			//即可接收主机名又可字符串表示的IP地址(IPV4: 点分十进制,IPV6: 十六进制)
    			const char* hostname,
    			//即可接收服务名也可接收字符串表示的十进制端口号
                const char* service, 
    			//精确控制输出,NULL表示反馈任何可用的结果;
    			//使用时可以设置ai_flags、ai_family、ai_socktype、ai_protocol四个字段,其余必须置为NULL
                const struct addrinfo* hints,
    			//指向一个反馈结果的链表
                struct addrinfo** result);

//getaddrinfo 将隐式的分配堆内存(result),需要配对的函数释放内存
void freeaddrinfo(struct addrinfo* res);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5mGbK3V0-1623659442724)(./Pic/table-5-6.png)]

getnameinfo

通过socket地址同时获取字符串表示的主机名(内部gethostbyaddr)和服务名(内部getservbyport)

#include <netdb.h>
int getnameinfo(const struct sockaddr* sockaddr,//传入的socket地址
                socklen_t addrlen,//地址长度
                char* host,//返回的主机名
              	socklen_t hostlen,//长度
                char* serv, //返回的服务名
                socklen_t servlen,//长度
                int flags//精确控制行为
               );

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRwmFVha-1623659442725)(./Pic/table-5-7.png)]

**getaddrinfo 和 getnameinfo 函数成功返回 0,失败返回错误码 **

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A9R9lrWV-1623659442727)(./Pic/table-5-8.png)]

#include <netdb.h>
//将数值错误码转换成易读字符串
const char* gai_strerror(int error);
名称 作用 特点
gethostbyname 通过主机名称获取主机的完整信息 不可重入(xxx_r版本可以)
gethostbyaddr 通过地址名称获取主机的完整信息 不可重入(xxx_r版本可以)
getservbyname 通过服务名称获取某个服务的完整信息 不可重入(xxx_r版本可以)
getservbyport 通过端口获取某个服务的完整信息 不可重入(xxx_r版本可以)
getaddrinfo 即能通过主机名获取IP地址(内部gethostbyname),也能通过服务名获取端口号(内部getservbyname) 是否可重入取决于调用的内部函数是否可重入
getnameinfo 通过socket地址同时获取字符串表示的主机名(内部gethostbyaddr)和服务名(内部getservbyport) 是否可重入取决于调用的内部函数是否可重入
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读书笔记_《Linux高性能服务器编程》_第 5 章:网络编程基础API 的相关文章

  • Linux 中热插拔设备时检测设备是否存在

    我正在运行 SPIcode http lxr free electrons com source drivers spi spi omap2 mcspi c在熊猫板上 我想知道其中的哪个功能code http lxr free electr
  • 为 Qt 应用程序创建 Linux 安装

    我刚刚用 Qt Creator 制作了一个很棒的程序 我对自己很满意 如何将其从台式机移至笔记本电脑 那么 最好的方法是安装程序 对吗 对于 Ubuntu 这是一个 Debian 软件包 对吗 我怎么做 有人这样做过吗 他们可以分享 QT
  • Inotify linux 监视子目录

    是否可以以这种模式监视目录 storage data usernames Download gt storage data Download 我需要监视每个用户的下载文件夹中是否进行了更改 也许我需要创建所有路径的列表 将其放入数组中 并在
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 从 TypeScript 运行任何 Linux 终端命令?

    有没有办法直接从 TypeScript 类中执行 Linux 终端命令 这个想法是做类似的事情 let myTerminal new LinuxTerminal let terminalResult myTerminal run sudo
  • 从多线程程序中调用 system()

    我们正在开发一个用 C 编写的多线程内存消耗应用程序 我们必须执行大量的 shellscript linux 命令 并获取返回码 读完之后article http www linuxprogrammingblog com threads a
  • 无需 cron 在后台发送邮件

    我想知道是否有一种方法可以运行 PHP 循环 以便在后台向订阅者发送几百封电子邮件 我的目标是格式化新闻通讯 单击发送 然后关闭浏览器或更改页面 当然 发送电子邮件的实际过程将在后台运行 不会因浏览器关闭而中断 我知道这可以通过 cron
  • 如何查找连接到 AF_INET 套接字的客户端的 UID?

    有什么方法或类似的东西ucred for AF UNIX如果是AF INET插座 TCP在我的例子中 找出连接到我的套接字的客户端的UID 还有 proc net tcp但它显示了UID of the creator插座的而不是连接的cli
  • Docker:处理 tar 文件时出错(退出状态 1):设置枢轴目录时出错:不是目录

    我是 Docker 新手 不知道是什么原因导致此错误或如何诊断它 任何有关此问题的具体帮助或有关首先检查何处以诊断此类问题的提示将不胜感激 我的 Dockerfile FROM java 8 Install maven RUN apt ge
  • Linux 桌面快捷方式和安装图标

    我需要添加什么到我的 spec文件来创建桌面快捷方式并在安装过程中为快捷方式分配一个图标 rpm 如果需要脚本 一个示例将非常有帮助 您在 Linux 下使用 desktop 文件作为图标 图标放置的位置取决于您使用的发行版和桌面环境 由于
  • 在主目录中安装库

    在 Linux Ubuntu 中 我尝试运行一个工具 但它显示错误 库丢失 我无权在系统中安装任何内容 或者根本无法从我的用户帐户执行 sudo 是否可以在我的主目录 没有 sudo 中安装缺少的库 在我的例子中为 libstdc so 6
  • PHP 致命错误:未找到“MongoClient”类

    我有一个使用 Apache 的网站 代码如下 当我尝试访问它时 我在 error log 中收到错误 PHP Fatal Error Class MongoClient not found 以下是可能错误的设置 但我认为没有错误 php i
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • 嵌入式Linux poll()不断返回

    我有一个特别的问题 当我知道没有什么可读时 民意调查不断返回 因此设置如下 我有 2 个文件描述符 它们构成fd设置民意调查监视 一种用于引脚从高到低的变化 GPIO 另一个用于代理输入 代理输入出现问题 处理的顺序是 启动main函数 然
  • Godaddy 托管上的 CakePHP 控制台

    我一直在努力让我的 CakePHP 网站在 Godaddy 网格托管 帐户上运行 我的蛋糕应用程序设置是从帐户的子目录托管的 并且可以通过子域访问 我必须调整我的 htaccess 文件才能使其正常工作 现在我需要让 CakePHP 控制台
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 无法加载 JavaHL 库。- linux/eclipse

    在尝试安装 Subversion 插件时 当 Eclipse 启动时出现此错误 Failed to load JavaHL Library These are the errors that were encountered no libs
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何在bash中使用jq从变量中包含的json中提取值

    我正在编写一个 bash 脚本 其中存储了一个 json 值 现在我想使用 Jq 提取该 json 中的值 使用的代码是 json val code lyz1To6ZTWClDHSiaeXyxg redirect to http examp

随机推荐

  • 交叉验证--关于最终选取模型的疑问

    看最下面对这个回答 2018 06 21 很多书上都说了交叉验证的方法 还有留出法的评估方法 西瓜书 他们也都说了多次抽样然后多次评估取平均的策略 这样是为了充分利用这个样本集的分布 这里有一个问题 那就是 既然是取平均 那这个分类器到底是
  • JAVA设计模式之Chain-of-Responsiblility模式

    当一个请求可以被多个对象处理 同时又无法确定到底有谁来处理该请求 这时 我们就需要让该请求在这些对象之间一个个的接力 如果当前对象可以处理请求则处理它 否则 传递给下一个对象处理 这就是责任链模式的思想 责任链模式的组件结构图如下 可以看出
  • Python+Selenium_UI自动化操作(8)——获取页面元素的标签+尺寸

    UI自动化 获取当前页面某元素的标签 尺寸 语法 1 标签名 tag name 2 size size 返回一个字典 包括height width class TestGetElementInfo unittest TestCase def
  • vue实现接口中得数据有变化就要实时得请求获取到最新数据

    1 使用 sockets 与服务器建立实时通信 接收数据变化推送在 created 生命周期中建立 sockets 连接 js created this socket io someUrl this socket on dataChange
  • [android] 百度地图开发 (一).申请AK显示地图及解决显示空白网格问题

    最近做android百度地图 但是使用baidumapapi v2 3 1 jar和libBaiduMapSDK v2 3 1 so显示百度地图时总是遇到问题 只显示网格而没有显示地图 网络连接和APIKey申请都是正确的 就是不知道为什么
  • 【GRU回归预测】基于麻雀算法优化门控循环单元SSA-GRU神经网络实现多输入单输出回归预测附matlab代码

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 matlab项目合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 更多Matlab仿真内容点击 智能优化算法 神经网络预测 雷达通信 无线传感器 信号处理 图像
  • CSS之Sass中的@mixin和@extend,使用详细(Sass中@mixin和@extend的区别)

    简介 mixin 该指令用于定义可重用的代码块 可以在需要的地方进行调用 通过 mixin指令 你可以将一组样式代码封装成一个mixin 并在需要的地方使用 include指令来调用这个mixin 这样可以避免重复编写相同的样式代码 提高代
  • 模拟退火算法 Simulated Annealing(SA)学习笔记

    1 模拟退火算法思想 所谓模拟退火就是模仿物质退火过程 物体温度高时分子运动剧烈 此时我们的算法接受新解的概率拉高 物体温度逐渐趋向平和时 此时我们算法接受新解更新的概率降低 首先物体刚开始处于非晶体状态 左图 我们将固体加温至充分高 固体
  • sync/atomic 库使用小结

    sync atomic 库提供了原子操作的支持 原子操作直接有底层CPU硬件支持 因而一般要比基于操作系统API的锁方式效率高些 本文对 sync atomic 中的基本操作进行一个简单的介绍 原子增值 用于对变量值进行原子增操作 并返回增
  • 聊天机器人和 Rasa 2.0 的新增功能

    目录 聊天机器人和 Rasa 2 0 的新增功能 文件夹和文件层次结构 配置 config yml Pipeline Policies Importers Domain domain yml Training Data Format NLU
  • 码点与代码单元

    码点与代码单元 码点 码点是指与一个编码表中的某个字符对应的代码值 在Unicode标准中 码点采用16进制书写 并加上U 例如U 0041就是拉丁字母A的码点 代码单元 UTF 16编码采用不同长度的编码表示所有Unicode码点 在基本
  • “12306”是如何支撑百万QPS的?

    12306抢票 极限并发带来的思考 每到节假日期间 一二线城市返乡 外出游玩的人们几乎都面临着一个问题 抢火车票 虽然现在大多数情况下都能订到票 但是放票瞬间即无票的场景 相信大家都深有体会 尤其是春节期间 大家不仅使用12306 还会考虑
  • Linux中的五种I/O模型

    概念说明 用户空间和内核空间 现在操作系统都是采用虚拟存储器 那么对32位操作系统而言 它的寻址空间 虚拟存储空间 为4G 2的32次方 操作系统的核心是内核 独立于普通的应用程序 可以访问受保护的内存空间 也有访问底层硬件设备的所有权限
  • OpenCV中对Mat矩阵加、减、乘、除、转置等操作的总结

    1 矩阵加 1 使用重载的 运算符 矩阵的加法是指两个矩阵对于位置的数值相加 使用OpenCv重载的 运算符 假设两个矩阵都为uchar类型 例如 Mat src1 Mat
  • 1.3 DLT645

    一 简介 目前市面的大部分的电表 通信都是遵循该协议 因为物理层使用RS 485 故为半双工通信 主站指终端设备 从站指多功能电能表 数据链路层 默认波特率2400 偶校验 8bit数据 1bit停止位 先传低位 后传高位 D0是字节最低有
  • uiautomator2学习5——一个简单的例子

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 uiautomator2学习5 一个简单的例子 写了个简单的例子 就是打开淘宝搜索钥匙扣的一个简单的代码 如下 import uiautomator2 as u2 d u2
  • Spring框架中IOC容器和Bean的配置

    一 IOC和DI的解释 1 IOC Inversion of Control 反转控制 在应用程序中的组件需要获取资源时 传统的方式是组件主动的从容器中获取所需要的资源 在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式 增加
  • Java基础——Map集合遍历方式

    1 方式一 键找值 先获取Map集合的全部键的Set集合 遍历键的Set集合 然后通过键提取对应值 涉及API 方法名称 说明 Set
  • 【导入file文件转数组】input -> type=‘file‘ -> list

    组件 admin文件 引用xlsx js import HandleImportFile from common xlsx js
  • 读书笔记_《Linux高性能服务器编程》_第 5 章:网络编程基础API

    第 5 章 Linux网络编程基础API 知识要点 socket 地址 API socket 基础 API 网络信息 API 1 socket 地址API 主机字节序和网络字节序 CPU 32位 的累加器一次至少可以装载 4 字节 即一个整