網絡編程基礎api

1. IP 協議

1.1 IP 分片

(1)IP 分片和重組主要依靠 IP 頭部三個字段:數據報標識、標志和片偏移

以太網幀的 MTU 是 1500 字節;

一個每個分片都有自己的 IP 頭部,它們都具有相同的標識值,有不同的片偏移(數據部分的長度必須是 8 的整數倍),除了最后一個分片外,其他分片都設置 MF 標志;
每個分片的總長度字段被設置為該分片的長度;

1.2 路由機制

執行 route 可以查看路由表
在這里插入圖片描述
第一項的目標地址是 default,即默認路由項,包含一個“G”標志,說明路由下一跳目標是網關;

  1. 查找路由表中和數據報目標的 IP 地址完全匹配的 IP 地址;
  2. 查找路由表中和數據報目標的 IP 地址具有相同網絡號的 IP 地址(網絡號為 IP 地址&&子網掩碼,匹配長度越長越優先);
  3. 選擇默認路由項;

ICMP 重定向報文會改變路由表緩沖,生成更合理的路由方式;

2. TCP 協議

TCP 是一對一的,UDP 適合多播和廣播;

UDP 中應用程序每次執行一個寫操作,就會發送一個 UDP 數據報;接收方必須及時針對每一個 UDP 數據報執行讀操作,否則會丟包,如果沒有足夠的應用程序緩沖區,UDP 數據可能被截斷;

2.1 TCP 狀態轉移

(1)服務器通過 listen 系統調用進入 LISTEN 狀態,監聽到某個連接請求時(收到 SYN),將該連接放入內核等待隊列,發送 SYN + ACK,收到 ACK 后,進入 ESTABLISHED 狀態;

(2)客戶端通過 connect 系統調用,該函數首先發送 SYN,使狀態轉移到 SYN_SENT 狀態;

connect 調用失敗的兩個場景:(立即返回初始的 CLOSED 狀態)

  1. 目標端口不存在,或其處于 TIME_WAIT 狀態,服務器返回 RST 段
  2. 目標端口存在,但 connect 在超時時間內未收到服務器的確認報文段

connect 調用成功,轉移至 ESTABLISHED 狀態;

(3)客戶端在 FIN_WAIT_2 狀態時,未等服務器關閉連接強行退出;

此時客戶端連接由內核接管,稱為孤兒連接;tcp_max_orphanstcp_fin_timeout 定義了內核能接管的孤兒連接數目及其在內存中生成的時間;

(4)TIME_WAIT 狀態存在的原因:

可靠的終止 TCP 連接
保證讓遲來的 TCP 報文段被丟棄

(5)異常終止連接;

應用可以通過 socket 選項 SO_LINGER 來發送 RST 報文段;

2.2 TCP 數據流

(1)交互數據:僅包含很少字節,對實時性要求高,如 telnet,ssh 等;

客戶端每個鍵入就會發送一個 TCP 數據報;客戶端會立即確認,服務器可能使用延遲確認;

(2)成塊數據:長度通常為最大數據長度,對傳輸效率要求高,如 ftp;

2.3 帶外數據

緊急指針指向帶外數據最后一個字節的下一個位置,因此僅能識別帶外數據的最后一個字節;

2.4 擁塞控制

控制發送窗口(SWND),即發送端能連續發送的 TCP 報文段的數量

3. HTTP 協議

HTTP 請求中的頭部字段可按任意順序排序,目標主機名是必須包含的頭部字段;

3.1 請求

(1)請求行;格式為:請求方法 ------ 目標資源 URL ------ 版本號(------ 代表空格或 \t(可能為多個));
(2)多個頭部字段行;一個頭部字段是一行,請求行和每個頭部字段行必須以< CR >< LF >結尾(回車符及換行符)
(3)空行;所有頭部字段之后,需要包含一個空行(回車符及換行符),標識頭部字段的結束
(4)可選消息體;若消息體為空,頭部字段必須包含該消息體長度的字段”Content-Length“

3.2 應答

(1)狀態行;
(2)頭部字段行;

HTTP 是一種無狀態的協議,使用額外的手段來保持 HTTP 連接狀態;
Cookie 是服務器發送給客戶端的特殊信息,客戶端每次向服務器發送請求時帶上這個信息,就可以幫助服務器區分不同客戶;

(3)空行;
(4)請求數據;

在這里插入圖片描述

4. 整體流程

本地名稱查詢:/etc/hosts 存儲了目標主機名及其對應 IP 地址

(1)如果在 /etc/hosts 未找到目標機器名對應的 IP 地址,會使用 DNS 服務;這個順序可由 /etc/host.conf 配置

(2)DNS 服務:首先讀取 /etc/resolv.conf,獲取 DNS 服務器的 IP 地址,發送 UDP 報文段;

到達 IP 層時,會查詢路由表,獲得下一跳的 IP 地址,再調用網絡驅動程序,根據這個地址獲得其 MAC 地址(如果沒有,會使用 ARP 協議)

5. socket

5.1 socket 地址族

5.1.1 字節序

(1)大端序:高位在內存低地址處(網絡字節序,JAVA 虛擬機采用大端序)
------- 小端序:高位在內存高地址處(主機字節序)

(2)字節序的轉換函數,long 函數通常轉換 IP 地址,short 通常轉換端口號;
在這里插入圖片描述
轉換函數源碼:通過移位實現;

5.1.2 通用 socket 地址

(1)socket 結構體
在這里插入圖片描述
sa_family 表示地址族類型;
sa_data 存放 socket 地址值,不同協議族有不同含義和長度,14 字節的 sa_data 無法完全容納多數協議族的地址值;

協議族地址族描述地址含義及長度
PF_UNIXAF_UNIXUNIX 本地域協議族文件路徑名,長度可達108字節
PF_INETAF_INETTCP/IPv4協議族16 位端口號和32位 P地址,共6字節
PF_INET6AF_INET6TCP/IPv6 協議族16 位端口號,32位流標識,128位IP地址,32位范圍ID,共26字節

(2)Linux 定義了新的通用 socket 地址結構體
在這里插入圖片描述
_ss_align 用于內存對齊作用;

5.1.3 專用 socket 地址

通用地址涉及位操作;

#include <sys/un.h>
struct sockaddr_un
{sa_family_t sin_family;  /*AF_UNIX*/char sun_path[108];		 /*文件路徑名*/
};
----------------------------------------------------------------
struct sockaddr_in
{sa_family_t sin_family;  /*AF_INET*/u_int16_t sin_port		 /*端口號, 要用網絡字節序表示*/struct in_addr sin_addr; /*IPv4 地址結構體*/
};
struct in_addr
{u_int32_t s_addr;		/*IPv4地址,要用網絡字節序表示*/
};
----------------------------------------------------------------
struct sockaddr_in6
{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;	/*暫未使用*/
};
struct in6_addr
{unsigned char sa_addr[16];		/*IPv6地址,要用網絡字節序表示*/
};

所有專用 socket 地址(以及 sockaddr_storage)類型在實際使用時都需要轉化為通用 socket 類型 sockaddr(強制轉換即可)

如何進行的轉換?

5.1.4 IP 地址轉換

注意:點分十進制字符串是主機字節序,整數為網絡序;

#include <arpa/inet.h>
/*
點分十進制轉換為整數
失敗返回 INADDR_NONE
*/
in_addr_t inet_addr( const char* strptr );  
/*
點分十進制轉換為整數,將結果存儲與 inp 指向結構中,
成功返回 1,失敗返回 0
*/
int inet_aton( const char* cp, struct in_addr* inp );
/*整數轉換為點分十進制*/
char* inet_ntoa( struct in_addr in );
----------------------------------------------------
/*
點分十進制字符串轉換為整數
成功返回1
失敗返回0,設置errno 
*/
int inet_pton( int af, const char* src. void* dst );
/*
整數轉換為點分十進制字符串
成功返回目標存儲單元地址
失敗返回 NULL 并設置 errno
*/
const char* inet_ntop( int af, const void* src. char* dst, socklen_t cnt );

這里注意:inet_ntoa函數內部使用靜態變量存儲轉換結果,函數返回值指向該靜態內存,是不可重入的(會互相干擾)

轉換結果存儲在 dst 指向內存中;af 指定地址族,可以是 AF_INET 或 AF_INET6;參數 cnt 指定目標存儲單元大小,取值參考下面;

#include <netinet/in.h>
#define INET_ADDRSTRLEN 16  	/*用于 IPv4 */
#define INET6_ADDRSTRLEN 46		/*用于 IPv6 */

5.2 操作 socket

5.2.1 創建

指定地址族;socket 是一個文件描述符;

#include <sys/types.h>
#include <sys/socket.h>
/*
成功返回 socket 文件描述符
失敗返回 -1 并設置 errno
*/
int socket( int domain, int type, int protocol );

(1)domain 指明協議族,PF_**;
(2)type 指定服務類型,SOCK_STREAM(流服務)和 SOCK_UGRAM(數據報)對 TCP/IP 而言,前者表示使用 TCP,后者為 UDP;

服務類型可以和標志進行與運算:SOCK_NONBLOCK(新創建的 socket 設為非阻塞) 和 SOCK_CLOEXEC (fork 創建子進程時在子進程關閉該 socket);

(3)protocol;應該設置為 0;

5.2.2 命名

socket 命名:將一個 socket 與 socket 地址綁定;命名后客戶端才知道如何連接它;客戶端通常不需要命名 socket,采用匿名方式(操作系統自動分配);

#include <sys/types.h>
#include <sys/socket.h>
/*
成功返回 0
失敗返回 -1 并設置 errno
EACCES 表示被綁定的地址是受包含的地址,僅超級用戶能夠訪問,例如普通用戶綁定知名端口
EADDRINUSE 被綁定的地址正在使用中,比如綁定到一個處于 TIME_WAIT 的 socket 地址
*/
int bind( int sockfd, const struct sockaddr* my_addr, socklen_t addrlen );

addrlen 指出 socket 地址的長度;

5.2.3 監聽 socket

創建監聽隊列以存放待處理的客戶連接;

#include <sys/socket.h>
/*
成功返回 0
失敗返回 -1 并設置 errno
*/
int listen( int sockfd, int backlog );

backlog 參數提示內核監聽隊列的最大長度,表示處于完全連接狀態(ESTABLISHED)的 socket 上限,典型值為 5;超過該值,服務器不再受理新的連接,客戶端收到 ECONNREFUSED 錯誤;

處于半連接狀態的 socket 上限由 /proc/sys/net/ipv4/tcp_max_syn_backlog 內核參數定義

5.2.4 接收連接

簡單的從 listen 監聽隊列中接收一個連接,不關心連接處于哪種狀態,例如建立連接后,斷開客戶端網絡或直接退出客戶端(處于 CLOSE_WAIT狀態),都能調用成功;

#include <sys/types.h>
#include <sys/socket.h>
/*
成功返回一個新的連接 socket,唯一標識了被接收的連接
失敗返回 -1 并設置 errno
*/
int accept( int sockfd, struct sockaddr *addr, socklen_t *addrlen );

sockfd 是 listen 系統調用監聽 socket;
addr 獲取遠端 socket 地址,該地址長度由 addrlen 指出;

accept調用成功返回的連接 socket 至少完成了三次握手的前兩個;

5.2.5 發起連接
/*
成功返回 0
失敗返回 -1 并設置 errno
*/
int connect( int sockfd, const struct sockaddr *serv_addr, socklen_t *addrlen );

serv_addr 為服務器監聽,socket,addrlen 為這個地址長度;

常見 errno:
ECONNREFUSED,目標端口不存在,連接被拒絕
ETIMEDOUT,連接超時

connect成功返回后,TCP 三次握手已完成

5.2.6 關閉連接

關閉連接只是將其引用計數減1,等其為0時,才真正關閉;

#include <unistd.h>
int close( int fd );

立即終止連接(不是將引用計數減1)

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

howto 取值為:

  1. SHUT_RD,關閉讀,不能對其執行讀操作,接收緩沖區的數據都被丟棄
  2. SHUT_WR,關閉寫,之前發送緩沖區數據會在真正關閉前發送出去,處于半連接狀態;
  3. SHUT_RDWR,都關閉

5.3 數據讀寫

對文件的讀寫操作 readwrite 可以使用,但有專門的系統調用,增加了對數據讀寫的控制;

5.3.1 TCP 數據讀寫
/*
失敗返回 -1 并設置 errno
*/
ssize_t recv( int sockfd, void *buf, size_t len, int flags );
ssize_t send( int sockfd, const void *buf, size_t len, int flags );

buf 和 len 分別為緩沖區的位置和大小,recv 成功返回實際讀到的數據,返回 0 意味對方關閉連接;
send 成功返回實際寫入的數據的長度
在這里插入圖片描述
flags 參數只對 sendrecv的當前調用生效,一般設為 0;

5.3.2 UDP 數據讀寫
/*
失敗返回 -1 并設置 errno
*/
ssize_t recvfrom( int sockfd, void *buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addrlen );
ssize_t sendto( int sockfd, const void *buf, size_t len, int flags const struct sockaddr* dest_addr, socklen_t addrlen );

recvfromsendto 也可用于面向連接的 socket 數據讀寫,只需最后兩個參數設為 NULL;

5.3.3 通用數據讀寫
#include <sys/socket.h>
ssize_t recvmsg( int sockfd, struct msghdr* msg, int flags );
ssize_t sendmsg( int sockfd, struct msghdr* msg, int flags );
struct msghdr
{void* msg_name;				/* socket地址 */socklen_t msg_namelen;		/* socket地址長度 */struct iovec* msg_iov;		/* 分散的內存塊,數組首地址 */int msg_iovlen;				/* 分散的內存塊數量 */void* msg_control;			/* 指向輔助數據的起始位置 */socklen_t msg_controllen;	/* 輔助數據的大小 */int msg_flags;			/* 復制函數中的 flags 參數,并在調用過程中更新 */
};
struct iovec
{void* iov_base;		/* 內存起始地址 */size_t iov_len;		/* 這塊內存長度 */
};

(1)對 TCP 協議,msg_name 必須設為 NULL;
(2)iovec 封裝了一塊內存,msg_iovlen 指定了這樣的對象有幾個;

recvmsg 而言,數據被讀取并存放在 msg_iovlen 塊分散內存中,這些內存由 msg_iov 指向的數組指定,稱為分散讀;
sendmsg 而言,msg_iovlen 塊分散內存中的數據將被一并發送,稱為集中寫;

(3)msg_flags 無需設定,會復制 recvmsg/sendmsg的 flags 參數;

5.4 帶外標記

判斷下一個被讀取到的數據是否是帶外數據,若是,返回 1 ,之后可以利用 MSG_OOB 標志的 recv 調用來接收,否則,返回 0;

#include <sys/socket.h>
int sockatmark( int sockfd );

5.5 地址信息函數

#include <sys/socket.h>
/* 
獲取 sockfd 對應本端 socket 地址
成功返回 0
失敗返回 -1 并設置 errno
*/
int getsockname( int sockfd, struct sockaddr* address, socklen_t* address_len );
/* 獲取 sockfd 對應遠端 socket 地址*/
int getpeername( int sockfd, struct sockaddr* address, socklen_t* address_len );

如果實際 socket 地址長度大于 address 指向內存,那么該 socket 地址會被截斷;

5.6 socket 選項

#include <sys/socket.h>
/* 
成功返回 0
失敗返回 -1 并設置 errno
*/
int getsockopt( int sockfd, int level, int option_name, void* option_value, socklen_t* restrict option_len );
/* 獲取 sockfd 對應遠端 socket 地址*/
int setsockopt( int sockfd, int level, int option_name, const void* option_value, socklen_t* restrict option_len );
leveloption name數據類型是否需要特定的設定時機說明
SOL_SOCKET(通用選項)SO_REUSEADDRint重用本地地址
SOL_SOCKETSO_RCVBUFintTCP 接收緩沖區大小
SOL_SOCKETSO_SNDBUFintTCP 發送緩沖區大小
SOL_SOCKETSO_RCVLOWATintTCP 接收緩沖區低水位標記
SOL_SOCKETSO_SNDLOWATintTCP 發送緩沖區低水位標記
SOL_SOCKETSO_LINGERlinger若有數據待發送,則延遲關閉

對服務器而言,有些 socket 選項只能在 listen 之前設定,對監聽 socket 設定的選項,對返回的連接 socket 將自動繼承這些選項;
對客戶端而言,這些選項應該在調用 connect 之前設定

(1)設置 TCP 接收/發送緩沖區大小時,系統會將其值加倍,并不得小于某個最小值;

TCP 接收緩沖區的最小值為 256 字節,發送緩沖區的最小值為 2048 字節

(2)SO_RCVLOWAT 和 SO_SNDLOWAT 一般被 IO 復用調用用來判斷 socket 是否可讀或可寫;

(3)SO_LINGER 控制 close 關閉 TCP 的行為;

默認調用 close 會立即返回,TCP 模塊負責把該 socket 對應 TCP 發送緩沖區中殘留的數據發送給對方;

struct linger
{int l_onoff;	/* 開啟(非0)還是關閉(0) */int l_linger;	/* 滯留時間 */		
};

l_onoff 為 0;該選項無效,close 采用默認行為;
l_onoff 不為 0,l_linger 為 0;close 立即返回,丟棄發送緩沖區數據,同時給對方發送一個 RST 報文段(異常終止一個連接);
l_onoff 不為 0,l_linger 大于 0;對于阻塞的 socket,close 等待 l_linger 時間,知道發送完所有殘留數據并得到對方確認,否則,將返回 -1 并設置 errno 為 EWOULDBLOCK;如果 socket 是非阻塞的,close立即返回,此時需要根據其返回值和 errno 來判斷殘留數據是否發送完畢;

5.7 網絡信息

網絡信息 API 作用:實現主機名代替 IP,服務名代替端口號

5.7.1 根據主機名/IP 獲取主機完整信息

如果在 /etc/hosts 未找到目標機器名對應的 IP 地址,會使用 DNS 服務;

#include <netdb.h>
struct hostent* gethostbyname( const char* name );
struct hostent* gethostbyaddr( const void* addr, size_t len, int type );
struct hostent
{char* h_name;			/*主機名*/char** h_aliases;		/*主機別名列表*/int h_addrtype;			/*地址族*/int h_length;			/*地址長度*/char** h_addr_list;		/*主機 IP 地址列表(網絡字節序給出)*/
};

addr 是目標主機的 IP 地址,len 是 addr 所指 IP 地址長度;
type 是 addr 所指 IP 地址類型,取值為 AF_INFT / AF_INFT6;

5.7.2 根據名稱/端口號獲取服務的完整信息

實際上讀取 /etc/services 文件獲取服務信息;

#include <netdb.h>
struct servent* getservbyname( const char* name, const char* proto );
struct servent* getservbyport( int port, const char* proto );
struct servent
{char* s_name;			/*服務名*/char** s_aliases;		/*服務別名列表*/int s_port;				/*端口號族*/char* s_proto;			/*服務類型,見下*/
};

proto 指定服務類型,取值為 ”tcp“、 ”udp“、NULL(所有類型的服務)

注意:上述四個函數是不可重入的(線程不安全),可重入版本函數名結尾加 _r

5.7.3 getaddrinfo

通過主機名/服務名獲得 IP/端口號,內部調用 gethostbynamegetservbyname

#include <netdb.h>
int getaddrinfo( const char* hostname, const char* service, const struct addrinfo* hints,struct addrinfo** result );
struct addrinfo
{int ai_flags;				/*見下*/int ai_family;				/*地址族*/int ai_socktype;			/*服務類型,SOCK_STREAM 或 SOCK_DGRAM */int ai_protocol;			/*具體網絡協議,通常設置為 0 */	socklen_t ai_addrlen;		/*socket 地址 ai_addr 的長度*/char* ai_canonname;			/*主機的別名*/struct sockaddr* ai_addr;	/*指向 socket 地址*/struct addrinfo* ai_next;	/*指向下一個addrinfo對象*/
};

result 指向一個鏈表,存儲 getaddrinfo返回結果
在這里插入圖片描述
hints 具有提示作用,當使用時,設置其前四個字段,其余必須被設置為 NULL;

getaddrinfo將給 result 隱式分配堆內存,必須通過下述函數進行釋放

void freeaddrinfo( struct addrinfo* res );
5.7.4 getnameinfo

通過socket 地址同時獲得 主機名和服務名,內部調用 gethostbyaddrgetservbyport

/*
成功返回 0
失敗返回錯誤碼
*/
void getnameinfo( const struct sockaddr* sockaddr, socklen_t addrlen, char* hostsocklen_t hostlen, char* serv, socklen_t servlen, int flags );

在這里插入圖片描述
在這里插入圖片描述
將錯誤碼轉化為字符串形式;

const char* gai_strerror( int error );

6. 參考

《Linux高性能服務器》

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

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

相關文章

css 十字分割線(含四等分布局)

核心技術 偽類選擇器含義li:nth-child(2)第2個 lili:nth-child(n)所有的lili:nth-child(2n)所有的第偶數個 lili:nth-child(2n1)所有的第奇數個 lili:nth-child(-n5)前5個 lili:nth-last-child(-n5)最后5個 lili:nth-child(7n)選中7的倍數 border-right: 3px solid white;borde…

EasyExcel-最簡單的讀寫excel工具類

前言&#xff1a; easyExcel 的官網文檔給的示例非常全&#xff0c;可以參考https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read 在此我貼出自己的工具類&#xff0c;可以直接用 導包 <dependency><groupId>com.alibaba</groupId><…

機器學習第15天:GBDT模型

??主頁 Nowl &#x1f525;專欄《機器學習實戰》 《機器學習》 &#x1f4d1;君子坐而論道&#xff0c;少年起而行之 ?? 文章目錄 GBDT模型介紹 Boosting 殘差 GBDT的缺點 python代碼實現 代碼 模型參數解釋 結語 GBDT模型介紹 GBDT&#xff08;Gradient Boos…

vivado $clog2函數

對于.v文件在vivado中是不支持&#xff0c;但是可以修改為.sv或更改文件屬性使用sytemverilog來支持。 /*** Math function: $clog2 as specified in Verilog-2005** clog2 0 for value 0* ceil(log2(value)) for value > 1** This implementatio…

php+mysql期末作業小項目

目錄 1、登錄界面 2、注冊界面 3、主界面 4、學生表界面 5 、查詢學生界面?編輯 6、修改學生信息界面?編輯 7、刪除學生信息界面 8、添加學生信息界面 9、后臺數據庫?編輯 一個簡單的php?mysql項目學生信息管理系統&#xff0c;用于廣大學子完成期末作業的參考&…

測試架構工程師需要具備哪些能力 ?

前言 相比于我們常見的研發架構師&#xff0c;測試架構師是近幾年才出現的一個崗位&#xff0c;當然崗位title其實沒有特殊的含義&#xff0c;在我看來測試架構師其實更像對某一類人的抽象稱呼和對其復合能力的期待及認可。 在聊這篇文章的主題之前&#xff0c;先來看這樣一個…

算法訓練營Day4(鏈表)

語言 采用的Java語言&#xff0c;一些分析也是用于Java&#xff0c;請注意。 24. 兩兩交換鏈表中的節點 24. 兩兩交換鏈表中的節點 - 力扣&#xff08;LeetCode&#xff09; 解題 這道題就是考驗鏈表的基礎操作&#xff0c;但是有個語言方面的知識需要去掌握&#xff0c;就是|…

TCP通信

第二十一章 網絡通信 本章節主要講解的是TCP和UDP兩種通信方式它們都有著自己的優點和缺點 這兩種通訊方式不通的地方就是TCP是一對一通信 UDP是一對多的通信方式 接下來會一一講解 TCP通信 TCP通信方式呢 主要的通訊方式是一對一的通訊方式&#xff0c;也有著優點和缺點…

如何在Android平板上遠程連接Ubuntu服務器使用code-server代碼開發

目錄 1.ubuntu本地安裝code-server 2. 安裝cpolar內網穿透 3. 創建隧道映射本地端口 4. 安卓平板測試訪問 5.固定域名公網地址 6.結語 1.ubuntu本地安裝code-server 準備一臺虛擬機,Ubuntu或者centos都可以&#xff0c;這里以VMwhere ubuntu系統為例 下載code server服務…

el-table 表格多選(后端接口搜索分頁)實現已選中的記憶功能。實現表格數據和已選數據(前端分頁)動態同步更新。

實現效果&#xff1a;&#xff08;可拉代碼下來看&#xff1a;vue-demo: vueDemo&#xff09; 左側表格為點擊查詢調用接口查詢出來的數據&#xff0c;右側表格為左側表格所有選擇的數據&#xff0c;由前端實現分頁。 兩個el-table勾選數據聯動更新 實現邏輯&#xff1a; el-…

低代碼開發到底是補品還是垃圾食品?

2023&#xff0c;低代碼徹底火了&#xff0c;甚至火到沒有點相關經驗&#xff0c;都不好意思出去面試的程度。 從業者對低代碼的發展充滿了想象&#xff0c;都認為未來低代碼的商業價值不可估量。 據Gartner的最新報告顯示&#xff0c;2023年全球低代碼開發技術市場規模預計將…

內部文件上傳以及渲染-接口API

文件上傳 地址http://172.16.0.118:8090/api/pm/base/affix/upload請求類型POSTContent-Type:text/plain;charsetutf-8參數 prjData {"prjId":"", "jobId":"3031b2c8-c809-4110-8e88-22c80a9c1ec0721aca89-96a1-4346-9b6e-022331d221d1Nec…

【EMNLP 2023】面向Stable Diffusion的自動Prompt工程算法BeautifulPrompt

近日&#xff0c;阿里云人工智能平臺PAI與華南理工大學朱金輝教授團隊合作在自然語言處理頂級會議EMNLP2023上發表了BeautifulPrompt的深度生成模型&#xff0c;可以從簡單的圖片描述中生成高質量的提示詞&#xff0c;從而使文生圖模型能夠生成更美觀的圖像。BeautifulPrompt通…

【MATLAB】MODWT分解+FFT+HHT組合算法

有意向獲取代碼&#xff0c;請轉文末觀看代碼獲取方式~也可轉原文鏈接獲取~ 1 基本定義 MODWT分解FFTHHT組合算法是一種綜合性的信號處理方法&#xff0c;它結合了經驗小波變換&#xff08;Empirical Wavelet Transform&#xff0c;EWT&#xff09;、快速傅里葉變換&#xff…

25.Oracle的回收站

oracle基礎系統學習目錄 01.CentOS7靜默安裝oracle11g 02.Oracle的啟動過程 03.從簡單的sql開始 04.Oracle的體系架構 05.Oracle數據庫對象 06.Oracle數據備份與恢復 07.用戶和權限管理 08.Oracle的表 09.Oracle表的分區 10.Oracle的同義詞與序列 11.Oracle的視圖 12.Oracle的…

愛智EdgerOS之深入解析如何應用愛智的視頻流模塊完成拉流

一、ONVIF 規范和常見視頻流傳輸協議 ① ONVIF 規范 隨著視頻監控產業鏈的成熟&#xff0c;市面上陸陸續續出現了各式各樣的網絡攝像設備&#xff0c;這些設備都需要通訊協議才能進行數據傳輸。早期廠商都采用私有協議&#xff0c;但是現在廠商分工明確&#xff0c;有的負責生…

程序員的技術成長攻略

推薦語&#xff1a;偶爾在公眾號看到的一篇文章&#xff0c;寫的非常好&#xff0c;在此分享給各位程序員兄弟&#xff0c;不光是對技術成長有幫助&#xff0c;其他領域也是同樣適用的&#xff01;建議反復閱讀&#xff0c;形成一套自己的技術成長策略。 原文地址&#xff1a;…

數據結構與算法:python棧和隊列的用法

python的棧和隊列其實都算作一個數組&#xff0c;棧從最后一個元素開始推出&#xff0c;隊列從第一個元素開始推出 # pop(0)刪除時間復雜度O(n) s [] #棧 q [] #隊列 s.append(1)#1入棧 q.append(1)#1入隊 s.pop()#出棧 q.pop(0)#出隊由于從第一個元素刪除需要挪動數組&…

【EI會議征稿】2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024)

2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024) 2024 Guangdong-Hong Kong-Macao Greater Bay Area International Conference on Digital Economy and Artificial Intelligence(DEAI2024) 2024年粵港澳大灣區數字經濟與人工智能國際學術會議(DEAI2024)由廣東科…

探索鴻蒙 TextInput組件

TextInput 根據組件名字&#xff0c;可以得知他是一個文本輸出框。 聲明代碼&#x1f447; TextInput({placeholder?:ResourceStr,text?:ResourceStr}); placeholder: 就是提示文本&#xff0c;跟網頁開發中的placeholder一樣的 text&#xff1a;輸入框當前的文本內容 特殊屬…