[C++ 網絡協議] 套接字和地址族、數據序列

目錄

1. 套接字

1.1 在Linux平臺下構建套接字

1.1.1 用于接聽的套接字(服務器端套接字)

1.1.2 用于發送請求的套接字(客戶端套接字)

1.2 在Windows平臺下構建套接字

1.2.1 Winsock的初始化

1.2.2 用于接聽的套接字(服務器端套接字)

1.2.3 用于發送請求的套接字(客戶端套接字)

1.3 Linux和Windows套接字的區別

1.4 套接字特性

1.4.1 socket函數

1.4.1.1 協議族信息(domain形參)

1.4.1.2? 套接字類型(Type形參)

1.4.1.2.1 面向連接的套接字(SOCK_STREAM)

1.4.1.2.2 面向消息的套接字(SOCK_DGRAM)

1.4.1.3 協議的最終選擇(protocol形參)

2. 地址族和數據序列

2.1 網絡地址

2.1.1 IPv4(常用)

2.1.1.1 網絡地址和主機地址

2.1.2 端口號

2.1.3 bind函數

2.1.3.1 sockaddr_in結構體

2.1.4 網絡字節序

2.1.5 字節序轉換

2.1.6 網絡地址的初始化和分配

2.1.6.1 inet_addr函數

2.1.6.2 inet_aton函數(Windows不存在此函數)

2.1.6.3 inet_ntoa函數(和inet_aton函數相反)

2.1.6.4 INADDR_ANY常數

2.1.6.5 WSAStringToAddress函數(只有Windows平臺有,不利于兼容性)

2.1.6.6 WSAAddressToString函數(只有Windows平臺有,不利于兼容性)

2.1.6.7 服務器端初始化IP地址時非常明確,為什么還要進行IP的初始化呢?

3.其余流程函數

3.1 進入連接等待狀態(listen函數)

3.2 受理客戶端連接請求(accpet函數)

3.3 客戶端請求連接(connect函數)

4. 基于TCP的服務器端/客戶端函數調用關系


網絡編程:編寫程序使兩臺連網的計算機進行數據交換。

1. 套接字

操作系統提供名為套接字的部件,套接字是網絡數據傳輸用的軟件設備,它能夠連接到因特網上,與遠程計算機進行數據傳輸。

1.1 在Linux平臺下構建套接字

對于Linux而言,socket操作與文件操作沒有區別。如:close函數不僅可以關閉文件也可以關閉套接字。

1.1.1 用于接聽的套接字(服務器端套接字)

第一步:調用socket函數創建套接字

#include<sts/socket.h>
int socket(int domain,int type,int protocol);
成功返回文件描述符,失敗返回-1

第二步:調用bind函數分配IP地址和端口號

#include<sts/socket.h>
int bind(int sockfd,struct sockaddr* myaddr,socklen_t addrlen);
成功返回0,失敗返回-1

第三步:調用listen函數轉為可接收請求狀態

#include<sts/socket.h>
int listen(int sockfd,int backlog);
成功返回0,失敗返回-1

第四步:調用accept函數受理連接請求

#include<sts/socket.h>
int accept(int sockfd,struct sockaddr* addr,socklen_t* addrlen);
成功返回文件描述符,失敗返回-1

accpet函數一直等待,直到有連接請求時,才會有返回值。

第五步:調用write函數發送數據

#include<unistd.h>ssize_t write(int fd,const void* buf,size_t nbytes);
成功則返回寫入的字節數,失敗返回-1

fd:文件描述符參數

buf:保存要傳輸數據的緩沖地址值

nbytes:要傳輸數據的字節數

第六步:關閉套接字

#include<unistd.h>int close(int fd);
成功返回0,失敗返回-1

fd:文件描述符參數。?

close函數不僅可以關閉文件也可以關閉套接字。 客戶端調用close會向服務端的客戶端套接字文件描述符傳遞EOF。

1.1.2 用于發送請求的套接字(客戶端套接字)

第一步:調用socket函數創建套接字

如上。

第二步:調用connect函數連接服務器端

#include<sts/socket.h>
int connect(int sockfd,struct sockaddr* serv_addr,socklen_t addrlen);
成功返回0,失敗返回-1

第三步:調用read函數讀取服務器傳輸的信息

#include<unistd.h>ssize_t read(int fd,void *buf,size_t nbytes);
成功則返回接收的字節數(但遇到文件結尾則返回0),失敗返回-1

fd:數據接收對象的文件描述符參數

buf:保存接收數據的緩沖地址值

nbytes:要接收數據的字節數

第四步:關閉套接字

如上。

1.2 在Windows平臺下構建套接字

在Windows平臺下構建套接字要先進行Winsock的初始化。

1.2.1 Winsock的初始化

初始化版本庫

#include<winsock2.h>int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
成功返回0,失敗返回非0的錯誤代碼值

wVersionRequested:WORD是通過typedef定義的unsigned short類型,這個參數是提供套接字版本信息。可借助MAKEWORD宏函數來構建版本信息,如:

MAKEWORD(1,2);       //主版本為1,副版本為2,返回0x0201
MAKEWORD(2,2);       //主版本為2,副版本為2,返回0x0202

lpWSAData:傳入WSADATA型結構體變量地址(LPWSADATA是WSADATA的指針類型),調用完函數后會將相關參數,填充到這個參數里。

WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{......
}

注銷版本庫

#include<winsock2.h>int WSACleanup(void);
成功返回0,失敗返回SOCKET_ERROR

銷毀Winsock相關庫,無法再調用Winsock相關函數。

1.2.2 用于接聽的套接字(服務器端套接字)

?第一步:調用socket函數創建套接字

#include <winsock2.h>
SOCKET socket(int af,int type,int protocol);
成功返回套接字句柄,失敗返回INVALID_SOCKET

第二步:調用bind函數分配IP地址和端口號

#include <winsock2.h>
int bind(SOCKET s,const struct sockaddr* name,int namelen);
成功返回0,失敗返回SOCKET_ERROR

第三步:調用listen函數轉為可接收請求狀態

#include <winsock2.h>
int listen(SOCKET s,int backlog);
成功返回0,失敗返回SOCKET_ERROR

第四步:調用accept函數受理連接請求

#include <winsock2.h>
SOCKET accept(SOCKET s,struct sockaddr* addr,int* addrlen);
成功返回文件描述符,失敗返回INVALID_SOCKET

accpet函數一直等待,直到有連接請求時,才會有返回值。

第五步:調用send函數發送數據

#include<winsock2.h>
int send(SOCKET s,const char* buf,int len,int flags);
成功返回傳輸字節數,失敗返回SOCKET_ERROR

?s:表示數據傳輸對象連接的套接字句柄值

buf: 保存待傳輸數據的緩沖地址值

len:要傳輸的字節數

flags:傳輸數據時用到的多種選項信息

第六步:關閉套接字

#include <winsock2.h>
int closeconnect(SOCKET s);
成功返回0,失敗返回SOCKET_ERROR

1.2.3 用于發送請求的套接字(客戶端套接字)

第一步:調用socket函數創建套接字

如上。

第二步:調用connect函數連接服務器端

#include <winsock2.h>
int connect(SOCKET s,const struct sockaddr* name,int namelen);
成功返回0,失敗返回SOCKET_ERROR

第三步:調用recv函數,接收服務器端傳來的數據

#include <winsock2.h>
int recv(SOCKET s,const char* buf,int len,int flags);
成功返回接收的字節數(收到EOF時為0),失敗返回SOCKET_ERROR

?s:表示數據接收對象連接的套接字句柄值

buf: 保存接收數據的緩沖地址值

len:要接收的最大字節數

flags:接收數據時用到的多種選項信息

第四步:關閉套接字

如上。

1.3 Linux和Windows套接字的區別

  1. 文件描述符和句柄的區別:

    在Linux中,文件描述符是不區分文件和套接字的,即兩個都是一樣的

    在Windows中,句柄是區分文件和套接字的,并不完全一樣。

    比較兩個系統的socket、listen和accept函數,可以發現,其實Linux的int sockfd就對應于Windows的SOCKET s,即SOCKET這個類型,就存有套接字句柄整形值,也類似于一種編號。

  2. write和send的區別:

???????? 在Linux中,有write也有send函數,來傳輸數據。

??????? 在windows中,send函數只是比Linux中的write函數多了最后的flag參數。

1.4 套接字特性

1.4.1 socket函數

int socket(
int domain,    //套接字中使用的協議族(Protocol Family)信息
int type,      //套接字數據傳輸類型信息
int protocol   //計算機間通信中使用的協議信息
);
成功返回文件描述符,失敗返回-1

?一個socket套接字=協議族+套接字類型+最終協議。

1.4.1.1 協議族信息(domain形參)

協議族:套接字通信中協議的分類。

名稱協議族
PF_INET(常用)IPv4互聯網協議族
PF_INET6IPv6互聯網協議族
PF_LOCAL本地通信的UNIX協議族
PF_PACKET底層套接字的協議族
PF_IPXIPX Novell協議族

1.4.1.2? 套接字類型(Type形參)

套接字類型:套接字的數據傳輸方式。

1.4.1.2.1 面向連接的套接字(SOCK_STREAM)

特點:

  1. 傳輸過程中數據不會丟失
  2. 按序傳輸數據
  3. 傳輸的數據不存在數據邊界
  4. 套接字連接必須一一對應(一個客戶端套接字對應服務器端的一個套接字,n個對應n個套接字)

總結:可靠的、按序傳遞的、基于字節的面向連接的數據傳輸方式的套接字注意接收和發送數據大小要相等。

特點:傳輸過程中數據不會丟失、傳輸的數據不存在數據邊界,解釋:

??????? 在接收的套接字內部,有一個由字節數組組成的緩沖區,從傳輸端傳過來的數據會先存儲到這個緩沖區里,如果緩沖區滿了,那么傳輸端就會停止傳輸,等待緩沖區中的數據被讀取完,再繼續傳輸。其中傳輸出錯,也會進行重傳服務,除特殊情況外,不會有數據丟失。

1.4.1.2.2 面向消息的套接字(SOCK_DGRAM)

特點:

  1. 快速傳輸
  2. 傳輸的數據可能丟失、損毀
  3. 傳輸的數據有數據邊界
  4. 限制每次傳輸的大小

總結:不可靠的,不按序傳遞的、以數據的高速傳輸為目的的套接字,不存在連接的概念注意接收和發送數據次數要相等。

特點:傳輸的數據具有數據邊界,解釋:

??????? 每次傳輸都有大小限制,如果超過了這個限制,那么就得分批發送,即意味著接收數據的次數應和傳輸次數相同。而面向連接的套接字,沒有這個要求。

1.4.1.3 協議的最終選擇(protocol形參)

第三個參數的意義:同一協議族中存在多個數據傳輸方式相同的協議

與套接字類型對應的:

  1. 面向連接的套接字:TCP套接字(IPPROTO_TCP),注意接收和發送數據大小要相等。
  2. 面向消息的套接字:UDP套接字(IPPROTO_UDP),注意接收和發送數據次數要相等。

2. 地址族和數據序列

IP(Internet Protocol網絡協議):為收發網絡數據而分配給計算機的值。

端口號:區分程序中創建的套接字而分配給套接字的序號。

2.1 網絡地址

分為兩類:IPv4(4字節地址族)、IPv6(16字節地址族)。

2.1.1 IPv4(常用)

IPv4標準的4字節IP地址,由網絡地址主機地址組成。

2.1.1.1 網絡地址和主機地址

IPv4分為如下A、B、C、D四種類型:

通過首字節可以判斷其屬于哪種類型:

首字節范圍類型
0~127A
128~191B
192~223C

向對應IP地址主機傳輸數據,是先通過網絡地址,查找到對應的路由器或交換機,再由路由器或交換機,根據主機ID將數據分發到主機上。如圖:將數據發送到203.211.172.103上,會先找到網絡地址為203.211.172的路由器,路由器再通過主機ID:103將數據傳輸給對應主機。

2.1.2 端口號

端口號由16位構成,可分配端口號范圍為0~65535,但0~1023是知名端口號,會分配給特定應用程序,所以應當分配此范圍之外的值。另外,雖然端口號不能重復,但TCP套接字和UDP套接字不會共用端口號,所以允許重復。例如:某TCP套接字用了9130端口,則其余TCP套接字不能使用此端口,但UDP套接字可以使用9130端口。

2.1.3 bind函數

#include<sts/socket.h>
int bind(int sockfd,struct sockaddr* myaddr,socklen_t addrlen);
成功返回0,失敗返回-1

2.1.3.1 sockaddr_in結構體

sockaddr_in:保存IPv4地址信息的結構體

struct sockaddr_in
{sa_family_t    sin_family;    //地址族uint16_t       sin_port;      //16位TCP/UDP端口號struct in_addr sin_addr;      //32位IP地址char           sin_zero[8];   //不使用
}struct in_addr
{in_addr_t      s_addr;        //32位IPv4地址
}struct sockaddr
{sa_family_t    sin_family;        //地址族char           sa_data[14];       //地址信息
}

數據類型是POSIX(可移植操作系統接口),POSIX是為UNIX系列操作系統設立的標準。

1.sin_family成員

2.sin_port成員

保存16位端口號,是以網絡字節序保存的。

3.sin_addr成員

保存32位IP地址信息,也是以網絡字節序保存的。

4.sin_zero成員

無特殊含義。只是為了使結構體sockaddr_in和sockaddr結構體大小保持一致插入的成員。

為什么我們平常的使用,要先填充 sockaddr_in結構體,再轉換為sockaddr結構體,而不直接填充sockaddr結構體呢?

答:因為sockaddr結構體中sa_data[14]數據的填充很麻煩,其中需包含IP地址和端口號,并且其余部分都要填充為0,才能使用。不如直接使用sockaddr_in結構體,再進行轉換。填充復雜的原因是sockaddr結構體并不僅僅為IPv4而設計。

2.1.4 網絡字節序

不同CPU中,向內存保存數據的方式有兩種,一種是正序,直接保存,一種是倒序保存,這意味著,CPU解析數據的方式也分為兩種:

  1. 大端序:高位字節存放到低位地址
  2. 小端序:高位字節存放到高位地址

所以,在數據傳輸時,必須統一方式,這種方式就稱為網絡字節序,即統一為大端序。即先把數據統一轉化為大端序的格式,再進行網絡傳輸,所以在填充sin_addr成員sin_port成員時需要以網絡字節序保存。

2.1.5 字節序轉換

主機字節序和網絡字節序的相互轉換,被稱為字節序轉換。有以下函數進行轉換:

unsigned short htons(unsigned short);    //把short類型數據從主機字節序轉換為網絡字節序
unsigned short ntohs(unsigned short);    //把short類型數據從網絡字節序轉換為主機字節序
unsigned long htonl(unsigned long);      //把long類型數據從主機字節序轉換為網絡字節序
unsigned long ntohl(unsigned long);       //把long類型數據從網絡字節序轉換為主機字節序

htons中的h表示主機(host)字節序。

htons中的n表示網絡(network)字節序。

htons中的s指的是short(short占2個字節,所以常用于端口號的轉換)。

htonl中的l值得是long(Linux中long類型占4個字節,所以常用于IP地址的轉換)。

2.1.6 網絡地址的初始化和分配

2.1.6.1 inet_addr函數

#include <arpa/inet.h>
in_addr_t inet_addr(const char *string);
成功則返回32位大端序整數型值,失敗則返回INADDR_NONE

這個函數幫助我們將字符串形式的IP地址轉換為32位整數型數據,同時也會進行網絡字節序轉換。 同時它也會檢測無效的IP地址

2.1.6.2 inet_aton函數(Windows不存在此函數)

inet_aton函數和inet_addr函數功能上相同。

#include <arpa/inet.h>
int inet_aton(const char *string,struct in_addr* addr);
成功則返回1,失敗則返回0

string:含有需轉換的IP地址信息的字符串地址值。

addr:將保存轉換結果的in_addr結構體變量的地址值。

2.1.6.3 inet_ntoa函數(和inet_aton函數相反)

#include <arpa/inet.h>
char* inet_ntoa(struct in_addr* addr);
成功則返回轉換的字符串地址值,失敗則返回-1

將網絡字節序32位整數型IP地址轉換為字符串形式

注意:在使用此函數時,返回的結果是一個指針,指向字符串信息的地址,當第二次使用這個函數時,這個地址存有的字符串信息會被覆蓋掉,所以在使用時,需要立即拷貝保存地址存有的字符串信息

2.1.6.4 INADDR_ANY常數

struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
...
addr.sin_addr.s_addr=htonl(INADDR_ANY);

INADDR_ANY常數:采用這種方式,會自動獲取運行服務器端的計算機的IP地址,不必親自輸入,并且,若同一計算機中分配有多個IP地址(路由器這種),則只要端口號一致,就可以從不同IP地址里接收數據。所以服務器端優先考慮這種方式。

2.1.6.5 WSAStringToAddress函數(只有Windows平臺有,不利于兼容性)

各種類型都是針對默認類型的typedef聲明。

#include <winsock2.h>
INT WSAStringToAddress
(LPTSTR AddressString,INT AddressFamily,LPWSAPROTOCOL_INFO lpProtocolInfo,LPSOCKADDR lpAddress,LPINT lpAddressLength
);
成功返回0,失敗返回SOCKET_ERROR

AddressString:含有IP地址和端口號的字符串地址值

AddressFamily:第一個參數中地址所屬的地址族信息

lpProtocolInfo:設置協議提供者(Provider),默認為NULL
lpAddress:保存地址信息的結構體變量地址值

lpAddressLength:第四個參數中傳遞的結構體長度所在的變量地址值。

2.1.6.6 WSAAddressToString函數(只有Windows平臺有,不利于兼容性)

各種類型都是針對默認類型的typedef聲明。

#include <winsock2.h>
INT WSAAddressToString
(LPSOCKADDR lpsaAddress,DWORD dwAddressLength,LPWSAPROTOCOL_INFO lpProtocolInfo,LPTSTR lpszAddressString,LPDWORD lpdwAddressStringLength
);
成功返回0,失敗返回SOCKET_ERROR

lpsaAddress:需要轉換的地址信息結構體變量地址值

dwAddressLength:第一個參數中結構體的長度
lpProtocolInfo:設置協議提供者(Provider),默認為NULL

lpszAddressString:保存轉換結果的字符串地址值
lpdwAddressStringLength:第四個參數中存有地址信息的字符串長度

2.1.6.7 服務器端初始化IP地址時非常明確,為什么還要進行IP的初始化呢?

因為:同一個計算機可能分配有多個IP地址,實際IP地址和計算機安裝的NIC數量相等。所以服務器需要決定應接收哪個IP地址傳來的數據,所以要服務器端要初始化IP地址。

3.其余流程函數

3.1 進入連接等待狀態(listen函數)

當調用了listen函數,服務器端會阻塞,等待連接請求狀態。意味著,只有在此之后客戶端才能調用connect函數。

#include<sts/socket.h>
int listen(
int sockfd,            //希望進入等待連接請求狀態的套接字文件描述符,傳遞的描述符套接字參數為服務器端套接字
int backlog            //連接請求等待隊列的長度。
);
成功返回0,失敗返回-1

如圖:

????????客戶端連接請求本身也是從網絡中接收到的一種數據,而接收數據就需要套接字,所以第一個參數服務器端套接字,就是充當門衛,可回復客戶端請求,傳輸"請求已收到"的信號數據。第二個參數就是可以規定,連接請求等候的隊列的大小,一般與服務器端特性有關,像頻繁請求的web端則至少要15。

3.2 受理客戶端連接請求(accpet函數)

#include<sys/socket.h>
int accpet(
int sock,                //服務器套接字的文件描述符
struct sockaddr* addr,   //保存發起連接請求的客戶端地址信息的變量地址值
socklen_t* addrlen       //第二個參數的結構體長度。
);
成功則返回套接字文件描述符,失敗則返回-1

accpet函數,受理連接請求等待隊列中,待處理的客戶端連接請求。函數調用成功,accept函數內部會產生用于數據I/O的套接字,并返回其文件描述符。這個套接字是自動創建的,并自動與發起連接請求的客戶端建立連接。

3.3 客戶端請求連接(connect函數)

#include<sys/socket.h>
int connect(
int sock,                    //客戶端套接字文件描述符
struct sockaddr* servaddr,   //保存目標服務器端地址信息的變量地址值
socklen_t addrlen            //第二個參數的變量長度
);
成功返回0,失敗返回-1

?connect函數只有以下情況之一才會返回:

  1. 服務器端接收連接請求,所謂的“連接請求”,并不意味著服務器端調用accpet函數,而是服務器端把連接請求信息記錄到等待隊列中。所以connect函數返回后并不立即進行數據交換
  2. 發生斷網等異常情況而中斷連接請求

4. 基于TCP的服務器端/客戶端函數調用關系

????????圖中的總體流程整理如下:服務器端創建套接字后連續調用bind、listen函數進入等待狀態,客戶端通過調用connect函數發起連接請求。需要注意的是,客戶端只能等到服務器端調用listen函數后才能調connect函數。同時要清楚,客戶端調用connect函數前,服務器端有可能率先調用accept函數。當然,此時服務器端在調用accept函數時進入阻塞( blocking)狀態,直到客戶端調connect函數為止。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36320.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36320.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36320.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pytest框架快速進階篇-pytest前置和pytest后置,skipif跳過用例

一、Pytest的前置和后置方法 1.Pytest可以集成unittest實現前置和后置 importunittestimportpytestclassTestCase(unittest.TestCase):defsetUp(self)->None:print(unittest每個用例前置)deftearDown(self)->None:print(unittest每個用例后置)classmethoddefsetUpClass…

jmeter中用戶參數和用戶定義的變量的區別

如果使用jmeter做過參數化的人都知道&#xff0c;參數化的方式有多種&#xff0c;其中一種就是使用用戶定義的變量&#xff0c;還有一種是使用用戶參數。那么&#xff0c;這兩個有什么異同呢&#xff1f; 一、先說相同的點&#xff1a; 1、都可以參數化&#xff0c;以供sample…

allure測試報告

使用pytest結合Allure進行測試報告生成的簡單教程 allure測試報告 Allure基于Java開發&#xff0c;因此我們需要提前安裝Java 8或以上版本的環境。 ◆安裝allure-pytest插件在DOS窗口輸入命令“pip3 install allure-pytest”&#xff0c;然后按“Enter”鍵。 下載安裝Allure…

使用 Docker 部署 canal 服務實現MySQL和ES實時同步

文章目錄 0. 環境介紹0. 前置步驟1. 安裝Kibana和Elasticsearch2. 安裝Canal和Canal Adapter2.1 修改數據庫配置2.1.1 修改配置2.1.2 驗證mysql binlog配置2.1.3 查看日志文件2.1.4 用JDBC代碼插入數據庫 2.2 安裝Canal Server2.3 安裝Canal Adapter修改兩處配置文件配置文件取…

Linux 命令篇

一、啟動網絡命令 ip addr 查看網卡信息 service network start 啟動網卡 service network stop 關閉網卡 service network restart 重啟網絡 二、pwd 命令 查看當前目錄的路徑 linux 下所有的絕對路徑都是從根目錄 "/" 開始 root:是linux下root用戶的根目…

初識mysql數據庫之引入mysql客戶端庫

目錄 一、下載第三方庫 1. 準備工作 1. 使用mysql官網提供的庫 2. yum源安裝 二、測試第三方庫是否可用 三、mysql常用接口介紹 1. 查看官方文檔 2. 初始化 3. 關閉mysql 4. 連接mysql 5. 下達sql指令 四、一個簡單的C客戶端庫連接mysql程序 1. 頭文件 2. 初始化…

FFmpeg接收UDP碼流

一、FFmpeg參數初始化&#xff1a; //在打開碼流前指定各種參數比如:探測時間/超時時間/最大延時等//設置緩存大小,1080p可將值調大av_dict_set(&options, "buffer_size", "8192000", 0);//以tcp方式打開,如果以udp方式打開將tcp替換為udpav_dict_set(…

Could not resolve host: mirrorlist.centos.org; Unknown error解決方法

今天服務器安裝完CentOS系統后&#xff0c;安裝網絡的時候&#xff0c;出現無法聯網yum yum -y install net-tools 以上代碼無法運行并報錯&#xff0c;這里我要提醒大家&#xff0c;如果在初始安裝的時候選中安裝網絡工具模塊就不用在安裝net-tools了&#xff0c;因為我選中…

Angular 性能優化實戰

Angular 性能優化實戰 Angular 是一個非常強大的前端框架&#xff0c;但是如果不注意性能優化&#xff0c;應用程序可能會變得非常慢并增加加載時間。 以下是一些Angular性能優化經驗的實戰建議&#xff1a; 1. 使用 OnPush 變更檢測策略 默認情況下&#xff0c;Angular檢查…

vite跨域配置踩坑,postman鏈接后端接口正常,但是前端就是不能正常訪問

問題一&#xff1a;怎么都鏈接不了后端地址 根據以下配置&#xff0c;發現怎么都鏈接不了后端地址&#xff0c;proxy對了呀。 仔細看&#xff0c;才發現host有問題 // 本地運行配置&#xff0c;及反向代理配置server: {host: 0,0,0,0,port: 80,// cors: true, // 默認啟用并允…

爆肝整理,性能測試方法與關鍵指標以及瓶頸定位思路,一篇貫通...

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 性能測試方法 1、…

Python編程實現百度AI開放平臺的接口對接方法,詳解和實踐指南

Python編程實現百度AI開放平臺的接口對接方法,詳解和實踐指南 引言 百度AI開放平臺提供了豐富的人工智能接口,包括語音識別、圖像識別、自然語言處理等功能。本文將通過Python編程,詳解如何對接百度AI開放平臺的接口,并提供實際代碼示例。準備工作 在開始之前,我們需要先完…

智能家居(1)---工廠模式實現燈光控制(繼電器組)以及火災報警模組的封裝

采用工廠模式以面向對象的方式來封裝各種設備模塊&#xff0c;方便整合項目以及后期的維護和擴展 mainPro.c&#xff08;主函數&#xff09; #include <stdio.h> #include "controlDevice.h"struct Devices *pdeviceHead NULL; //設備工廠鏈…

抓包工具Fiddler下載與安裝

一、Fiddler介紹 1.Fiddler簡介 Fiddler 是一款免費、靈活、操作簡單、功能強大的 HTTP 代理工具&#xff0c;是目前最常用的 HTTP 抓包工具之一。可以抓取所有的 HTTP/HTTPS 包、過濾會話、分析請求詳細內容、偽造客戶端請求、篡改服務器響應、重定向、網絡限速、斷點調試等…

數據結構刷題訓練:隊列實現棧

目錄 前言 1. 題目&#xff1a;使用隊列實現棧 2. 思路 3. 分析 3.1 創建棧 3.2入棧 3.3 出棧 3.4 棧頂數據 3.5 判空和 “ 棧 ” 的銷毀 4. 題解 總結 前言 我們已經學習了棧和隊列&#xff0c;也都實現了它們各自的底層接口&#xff0c;那么接下我們就要開始棧和隊列的專項刷…

go內存管理機制

golang內存管理基本是參考tcmalloc來進行的。go內存管理本質上是一個內存池&#xff0c;只不過內部做了很多優化&#xff1a;自動伸縮內存池大小&#xff0c;合理切割內存塊。 基本概念&#xff1a; Page&#xff1a;頁&#xff0c;一塊 8 K大小的內存空間。Go向操作系統申請和…

2.Model、ModelMap和ModelAndView的使用詳解

1.前言 最近SSM框架開發web項目&#xff0c;用得比較火熱。spring-MVC肯定用過&#xff0c;在請求處理方法可出現和返回的參數類型中&#xff0c;最重要就是Model和ModelAndView了&#xff0c;對于MVC框架&#xff0c;控制器Controller執行業務邏輯&#xff0c;用于產生模型數據…

Spring Cloud構建微服務斷路器介紹

什么是斷路器 斷路器模式源于Martin Fowler的Circuit Breaker一文。“斷路器”本身是一種開關裝置&#xff0c;用于在電路上保護線路過載&#xff0c;當線路中有電器發生短路時&#xff0c;“斷路器”能夠及時的切斷故障電路&#xff0c;防止發生過載、發熱、甚至起火等嚴重后果…

【Redis】使用Docker鏡像配置集群時的Operation timed out問題

不知道有沒有小伙伴跟我一樣是使用的Docker鏡像進行Redis集群案例模擬的&#xff08;三臺虛擬機確實帶不動 &#xff09;&#xff0c;然后我遇到了一個問題&#xff1a;Could not connect to Redis at 172.17.0.2:6379: Operation timed out 172.17.0.2是我其中一個Redis實例的…

如何測試Linux磁盤的讀寫速度

在Linux系統中也有很多命令可以測試硬盤的讀寫速度指標。以下是幾個常用命令&#xff08;注意&#xff1a;在執行測試命令之前&#xff0c;請務必備份數據以避免數據丟失&#xff01; 1、dd 命令 首先掛載磁盤 mount /dev/sdb /testdd 命令可用于進行硬盤讀寫速度測試。 例…