linux網絡編程、socket編程

進程間通信:
特點:依賴于內核,造成缺陷——無法實現多機通信。

網絡:
地址:由IP地址(IP地址是IP協議提供的一種統一的地址格式,它為互聯網上的每一個網絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差異。)和端口號構成(所謂的端口,就好像是門牌號一樣,客戶端可以通過ip地址找到對應的服務器端,但是服務器端是有很多端口的,每個應用程序對應一個端口號,通過類似門牌號的端口號,客戶端才能真正的訪問到該服務器。為了對端口進行區分,將每個端口進行了編號,這就是端口號 ,端口包括邏輯端口和物理端口兩種類型),實際上是通過IP地址+端口號來區分不同服務的,端口號提供了一種訪問通道,服務器一般都是通過知名端口號來識別的。例如:對于每個TCP/IP實現來說,FTP服務器的TCP端口號就是21,每個Talnet服務器的TCP端口號都是23,每個TFTP(簡單文件傳送協議)服務器的UDP端口號都是69.

數據交流:
當涉及到數據交流的時候就會涉及到協議(說白了就是數據格式),例如:http(超文本傳輸協議是一個簡單的請求-響應協議,它通常運行在TCP之上。它指定了客戶端可能發送給服務器什么樣的消息以及得到什么樣的響應。請求和響應消息的頭以ASCII形式給出;而消息內容則具有一個類似MIME的格式。這個簡單模型是早期Web成功的有功之臣,因為它使開發和部署非常地直截了當。)、tcp(傳輸控制協議是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,由IETF的RFC 793定義。)、udp(Internet 協議集支持一個無連接的傳輸協議,該協議稱為用戶數據報協議(UDP,User Datagram Protocol)。UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。RFC 768描述了 UDP。)

socket套接字:

  • 所謂套接字(Socket),就是對網絡中不同主機上的應用進程之間進行雙向通信的端點的抽象。一個套接字就是網絡上進程通信的一端,提供了應用層進程利用網絡協議交換數據的機制。從所處的地位來講,套接字上聯應用進程,下聯網絡協議棧,是應用程序通過網絡協議進行通信的接口,是應用程序與網絡協議根進行交互的接口。
  • 所謂socket網絡編程,也叫作套接字網絡編程,套接字網絡編程用到的協議TCP協議和UDP協議的用的比較多。

TCP和UDP協議的區別:

  • 連接方面區別:TCP提供面向連接的傳輸,通信前要先建立連接(三次握手機制)(如打電話要先撥號建立連接)。UDP是無連接的,面向報文的,即發送數據之前不需要建立連接。
  • 安全方面的區別:TCP提供可靠的服務,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達。UDP盡最大努力交付,即不保證可靠交付。
  • 傳輸效率的區別:TCP傳輸效率相對較低。UDP傳輸效率高,適用于對高速傳輸和實時性有較高的通信或廣播通信。
  • 連接對象數量的區別:TCP連接只能是點到點、一對一的。UDP支持一對一,一對多,多對一和多對多的交互通信。
  • TCP首部開銷20字節,UDP的首部開銷小,只有8個字節

字節序:
字節序,即字節在電腦中存放時的序列與輸入(輸出)時的序列是先到的在前還是后到的在前。計算機硬件有兩種儲存數據的方式:大端字節序(big endian)和小端字節序(little endian)。

為什么會有小端字節序?

  • 計算機電路先處理低位字節,效率比較高,因為計算都是從低位開始的。所以,計算機的內部處理都是小端字節序。
  • 但是,人類還是習慣讀寫大端字節序。所以,除了計算機的內部處理,其他的場合幾乎都是大端字節序,比如網絡傳輸和文件儲存。

常見序:

  • Little endian(小端字節序):將低序字節存儲在起始地址
  • Big endian(大端字節序):將高序字節存儲在起始地址
  • 網絡協議指定了通訊字節序—大端
  • 只有在多字節數據作為整體處理時才需要考慮字節序
  • 運行在同一臺計算機上的進程相互通信時,一般不用考慮字節序
  • 異構計算機之間通訊,需要轉換自己的字節序為網絡字節序

什么是高低位:

  • 給一個十進制整數,123456,很明顯左邊的是高位,右邊的是低位。計算機也是這樣認為的。給一個16進制數(四個二進制表示),0x12345678,以字節為單位,從高位到低位依次是 0x12、0x34、0x56、0x78。
  • 例子:在內存中雙字0x01020304(DWORD)的存儲方式
    地址從低到高:4000->4001->4002->4003
    小端字節序: 04 03 02 01
    大端字節序:01 02 03 04

socket編程步驟:

可以把服務器與客戶端之間的場景看做以下場景:一個客戶端走到五座房子(5個服務器)的面前,要訪問這五座房子中的一座房子中的一間房間。當客戶端不知道去哪一間房子時,這時候有一個人在樓上喊我是說漢語的(TCP/UDP)服務器,我的樓號是…(IP地址),我的房間號是…(端口號),然后客戶端就可以獲取服務器IP和服務器端口號進行連接。

在這里插入圖片描述

服務器端創建步驟:

  • 服務器端創建套接字(socket函數),返回網絡描述符,后續用網絡描述符進行操作
  • bind()為套接字添加信息,指定服務器自己的IP地址和端口號
  • 監聽網絡連接(listen()函數)
  • 監聽到有客戶端接入,接收一個連接(accept()函數)
  • 數據交互(利用read函數從網絡上面讀數據,利用write函數向網絡上面寫數據)
  • 關閉套接字(close()函數),斷開連接

客戶端創建步驟:

  • socket()創建一個通道
  • connect()連接服務器,根據IP地址和端口號
  • 然后進行讀寫操作
  • 最后關閉套接字斷開連接

三次握手和一次揮手:
當客戶端調用connect時,觸發了連接請求,向服務器發送了SYN J包,這時connect進入阻塞狀態;服務器監聽到連接請求,即收到SYN J包,調用accept函數接收請求向客戶端發送SYN K ,ACK J+1,這時accept進入阻塞狀態;客戶端收到服務器的SYN K ,ACK J+1之后,這時connect返回,并對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,連接建立。

socket編程函數介紹

socket()函數:

#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain, int type, int protocol);
功能:這個函數建立一個協議族為domain、協議類型為type、協議編號為protocol的套接字文件描述符。參數:domain:函數socket()的參數domain用于設置網絡通信的域函數socket()根據這個參數選擇通信協議的族,通常為AF_INET,表示互聯網協議族(TCP/IP協議族)。通信協議族在文件sys/socket.h中定義。協議族決定了socket的地址類型,在通信中必須采用對應的地址domain的值及含義:AF_INET、PF_INET:      IPV4因特網域AF_INET6:              IPV6因特網域AF_UNIX:                Unix域AF_ROUTE:               路由套接字AF_KEY:                 密鑰套接字AF_UNSPEC:              未指定PF_UNIX,PF_LOCAL:      本地通信type:指定socket類型常用的socket類型有:SOCK_STREAM:  Tcp連接,提供序列化的、可靠的、雙向連接的字節流,使用TCP協議。支持帶外數據傳輸SOCK_DGRAM:   數據報套接字定義了一種無連接的報,數據通過相互獨立的報文件進行傳輸,是無序的,并且不保證是可靠的、無差錯的、使用數據報協議UDP連接(無連接狀態的消息)SOCK_RAW:     RAW類型,允許程序使用底層協議,原始套接字允許對底層協議如IP/ICMP進行直接訪問,功能強大但使用較為不便,主要用于協議的開發SOCK_PACKET:  這是一個專用類型,不能呢過在通用程序中使用SOCK_SEQPACKET:序列化包,提供一個序列化的、可靠的、雙向的基本連接的數據傳輸通道,數據長度定常。每次調用讀系統調用時數據需要將全部數據讀出protocol:故名思意,就是指定協議.常用的協議有:IPPROTO_TCP:TCP傳輸協議IPPTOTO_UDP:UDP傳輸協議IPPROTO_SCTP:STCP傳輸協議IPPROTO_TIPC:TIPC傳輸協議返回值:如果函數調用成功,會返回一個標識這個套接字的文件描述符,失敗的時候返回-1
  • 注意: 并不是上面的type和protocol可以隨意組合的,如SOCK_STREAM不可以跟IPPROTO_UDP組合。當protocol為0時,會自動選擇type類型對應的默認協議。
  • 當我們調用socket創建一個socket時,返回的socket描述字它存在于協議族(address family,AF_XXX)空間中,但沒有一個具體的地址。如果想要給它賦值一個地址,就必須調用bind()函數,否則就當調用connect()、listen()時系統會自動隨機分配一個端口。

bind()函數:

#include<sys/types.h>
#include<sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:正如上面所說bind()函數把一個地址族中的特定地址賦給socket。例如對應AF_INET、AF_INET6就是把一個ipv4或ipv6地址和端口號組合賦給socket。參數:sockfd:即socket描述字,它是通過socket()函數創建了唯一標識一個socket。bind()函數就是將給這個描述字綁定一個名字。addr:一個const struct sockaddr *指針,指向要綁定給sockfd的協議地址這個地址結構根據地址創建socket時的地址協議族的不同而不同。如ipv4對應的是: struct sockaddr{unsigned short as_familf;//協議族char sa_data[14];//IP+端口號}同等替換為:使用時,強轉:(struct sockaddr *)&my_addr struct sockaddr_in {sa_family_t    sin_family; /* 協議族: AF_INET */in_port_t      sin_port;   /* 端口號,一般用5000以上,低于3000的是操作系統的關鍵端口,這個要將它轉化為網絡字節序*/struct in_addr sin_addr;   /* IP地址結構體*/unsigned char sin_zero[8]/*填充沒有實際意義只是為跟sockaddr結構體在內存中對齊,這樣兩者才能相互轉換*/};/* Internet address. */struct in_addr {uint32_t       s_addr;     /* address in network byte order */};ipv6對應的是: struct sockaddr_in6 { sa_family_t     sin6_family;   /* AF_INET6 */ in_port_t       sin6_port;     /* port number */ uint32_t        sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr;     /* IPv6 address */ uint32_t        sin6_scope_id; /* Scope ID (new in 2.4) */ };struct in6_addr { unsigned char   s6_addr[16];   /* IPv6 address */ };Unix域對應的是: #define UNIX_PATH_MAX    108struct sockaddr_un { sa_family_t sun_family;               /* AF_UNIX */ char        sun_path[UNIX_PATH_MAX];  /* pathname */ };addrlen:對應的是地址的長度,結構體大小。返回值:bind()函數的返回值為0時表示綁定成功,-1表示綁定失敗
  • 通常服務器在啟動的時候都會綁定一個眾所周知的地址(如ip地址+端口號),用于提供服務,客戶就可以通過它來接連服務器;而客戶端就不用指定,有系統自動分配一個端口號和自身的ip地址組合。這就是為什么通常服務器端在listen之前會調用bind(),而客戶端就不會調用,而是在connect()時由系統隨機生成一個。
  • 在將一個地址綁定到socket的時候,請先將主機字節序轉換成為網絡字節序,而不要假定主機字節序跟網絡字節序一樣使用的是Big-Endian。請謹記對主機字節序不要做任何假定,務必將其轉化為網絡字節序再賦給socket。

IP地址轉換API:

舊版本:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
功能:將點分十進制IP轉化為網絡字節序存放在addr中,并返回該網絡字節序對應的整數。
參數:輸入參數cp包含ASCII表示的IP地址。輸出參數inp是將要用新的IP地址更新的結構。
返回值:如果這個函數成功,函數的返回值非零。如果輸入地址不正確則會返回零。使用這個函數并沒有錯誤碼存放在errno中,所以他的值會被忽略。in_addr_t inet_addr(const char *cp);
功能:將點分十進制IP轉化為網絡字節序(二進制位的大端存儲)。
返回值;如果失敗:返回INADDR_NONE;如果成功:返回IP對應的網絡字節序的數;char *inet_ntoa(struct in_addr in);
功能:把網絡格式的ip地址轉化為字符串形式
inet_network函數in_addr_t  inet_network(const char *StrIP)
功能: 將點分十進制IP轉化為主機字節序(二進制位小端存儲)。
返回值:如果失敗:返回-1;如果成功:返回主機字節序對應的數;
舊版本的只能處理IPv4的ip地址
不可重入函數
注意參數是struct in_addr新版本:
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
新版本的支持IPv4和IPv6
可重入函數
其中inet_pton和inet_ntop不僅可以轉換IPv4的in_addr,
還可以轉換IPv6的in6_addr,因此函數接口是void *addrptr。

listen()、connect()函數:
如果作為一個服務器,在調用socket()、bind()之后就會調用listen()來監聽這個socket,如果客戶端這時調用connect()發出連接請求,服務器端就會接收到這個請求。

#include<sys/types.h>
#include<sys/socket.h>
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:內核為任何一個給定監聽者套接字,維護兩個隊列:1、未完成隊列,每個這樣的SYN報文段對應其中一項已由某個客戶端發出并到達服務器,而服務器正在等待相應的TCP三次握手過程,這些套接字處于SYN_REVD狀態2、已完成隊列,每個已完成TCP三次握手過程的客戶端對應其中一項,這些套接字處于ESTABLISHED狀態。參數:listen函數的第一個參數即為要監聽的socket描述字服務器的描述字第二個參數為相應socket可以排隊的最大連接個數。listen()并未開始連線,只是設置socket的listen模式。listen函數只用于服務器端。socket()函數創建的socket默認是一個主動類型的,listen函數將socket變為被動類型的,等待客戶的連接請求。connect函數的第一個參數即為客戶端的socket描述字,第二參數為服務器的socket地址,第三個參數為socket地址的長度。客戶端通過調用connect函數來建立與TCP服務器的連接。返回值:listen函數:成功返回0, 失敗返回-1.connect函數:成功返回0, 失敗返回-1.

accept()函數:
TCP服務器端依次調用socket()、bind()、listen()之后,就會監聽指定的socket地址了。TCP客戶端依次調用socket()、connect()之后就向TCP服務器發送了一個連接請求。TCP服務器監聽到這個請求之后,就會調用accept()函數取接收請求,這樣連接就建立好了。之后就可以開始網絡I/O操作了,即類同于普通文件的讀寫I/O操作。

#include<sys/types.h>
#include<sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
參數:accept函數的第一個參數為服務器的socket描述字,第二個參數為指向struct sockaddr *的指針,用于返回客戶端的協議地址,不關心可以設置為NULl。第三個參數為協議地址的長度。返回值:如果accpet成功,那么其返回值是由內核自動生成的一個全新的描述字,代表與返回客戶的TCP連接。失敗時返回-1
  • 注意: accept的第一個參數為服務器的socket描述字,是服務器開始調用socket()函數生成的,稱為監聽socket描述字;而accept函數返回的是已連接的socket描述字。一個服務器通常通常僅僅只創建一個監聽socket描述字,它在該服務器的生命周期內一直存在。內核為每個由服務器進程接受的客戶連接創建了一個已連接socket描述字,當服務器完成了對某個客戶的服務,相應的已連接socket描述字就被關閉。

數據的收發:

一般用read/write函數,當然還有其他函數:

  • read/write
  • recv()/send()
  • readv()/writev()
  • recvmsg()/sendmsg()(多在UDP連接時使用)
  • recvfrom()/sendto()(多在UDP連接時使用)
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

recv()/send()函數:
在這里插入圖片描述

close()函數:
在服務器與客戶端建立連接之后,會進行一些讀寫操作,完成了讀寫操作就要關閉相應的socket描述字,好比操作完打開的文件要調用fclose關閉打開的文件。

#include <unistd.h>
int close(int fd);close一個TCP socket的缺省行為時把該socket標記為以關閉
然后立即返回到調用進程。該描述字不能再由調用進程使用
也就是說不能再作為read或write的第一個參數。注意:close操作只是使相應socket描述字的引用計數-1只有當引用計數為0的時候,才會觸發TCP客戶端向服務器發送終止連接請求。

網絡字節序和主機字節序的轉換:

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
h表示host,n表示network,l表示32位長整數,s表示16位短整數。
如果主機是小端字節序,這些函數將參數做相應的大小端轉換然后返回,
如果主機是大端字節序,這些函數不做轉換,將參數原封不動地返回。

服務端實現可被連接功能:

#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
//#include<linux/in.h> 頭文件之間可能造成沖突這個頭文件就和#include <arpa/inet.h>沖突
#include <arpa/inet.h>
#include<stdlib.h>
#include<string.h>
#include <sys/wait.h>
#include<pthread.h>
struct num
{int fd;char*write;
};
void* writeMsg(void*arg)
{int i;struct num Part;Part.write=((struct num*)arg)->write;Part.fd=((struct num*)arg)->fd;while(1){if(i==1){getchar();}i=1;memset(Part.write,'\0',128);printf("輸入要給客戶端的內容:\n");scanf("%[^\n]",Part.write);write(Part.fd,Part.write,128);}
}
int main()
{struct sockaddr_in IP;struct sockaddr_in CLI;//客戶端信息struct num CAN;int socketre;int bindre;int i=0;int newfd;pid_t fpid;pthread_t sontd;char* writebuf;char* readbuf;readbuf=(char*)malloc(128);writebuf=(char*)malloc(128);int len=sizeof(struct sockaddr_in);socketre=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(socketre==-1){printf("create fail\n");perror("socket");exit(-1);}memset(&IP,'\0',len);memset(&CLI,'\0',len);IP.sin_family=AF_INET;IP.sin_port=htons(8686);IP.sin_addr.s_addr=inet_addr("192.168.1.183");bindre=bind(socketre,(struct sockaddr*)&IP,len);if(bindre==-1){perror("bind");printf("bind fail\n");exit(-1);}listen(socketre,10);while(1){newfd=accept(socketre,(struct sockaddr*)&CLI,&len);if(newfd==-1){perror("accept");printf("accept fail\n");exit(-1);}printf("連接成功\n");printf("get client:%s\n",inet_ntoa(CLI.sin_addr));CAN.write=writebuf;CAN.fd=newfd;fpid=fork();if(fpid==0){pthread_create(&sontd,NULL,writeMsg,(void*)&CAN);while(1){memset(readbuf,'\0',128);if(read(newfd,readbuf,128)!=0){if(strcmp(readbuf,"quit")==0){write(newfd,"server is out",13);close(newfd);pthread_cancel(sontd);break;}printf("接受到消息:%s\n",readbuf);printf("輸入要給客戶端的內容:\n");}else{printf("與客戶端斷開連接\n");}}}if(fpid>0){waitpid(fpid,NULL,WNOHANG | WUNTRACED);}}return 0;
}

如果有手機的話可以下載TCP手機助手,進行連接服務器,沒有該軟件可以用以下客戶端代碼:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include<pthread.h>
struct Client
{char* write;int fd;
};
void* del(void*arg)
{struct Client CAN;CAN.write=((struct Client*)arg)->write;CAN.fd=((struct Client*)arg)->fd;while(1){memset(CAN.write,'\0',128);printf("請輸入要發送給服務端的消息:\n");scanf("%s",CAN.write);write(CAN.fd,CAN.write,strlen(CAN.write));}
}
int main()
{int socketfd;int conre;char*writebuf;char*readbuf;pthread_t th;struct Client CL;struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(8686);addr.sin_addr.s_addr=inet_addr("192.168.1.183");socketfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(socketfd==-1){printf("socket create fail\n");perror("socket");exit(-1);}conre=connect(socketfd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in));if(conre==-1){printf("connect fail\n");perror("connect");exit(-1);}writebuf=(char*)malloc(128);readbuf=(char*)malloc(128);CL.write=writebuf;CL.fd=socketfd;pthread_create(&th,NULL,del,(void*)&CL);while(1){memset(readbuf,'\0',128);read(socketfd,readbuf,128);printf("獲取到服務端數據:%s\n",readbuf);printf("請輸入要發送給服務端的消息:\n");}return 0;
}

補充:

  • 當我們想用一個結構體或者聯合體時,可以進入/usr/include/這個文件夾下面,查找看看頭文件里面有沒有包含想要使用的結構體或者聯合體,使用以下命令:
cd /usr/include/
進入文件夾
grep "struct sockaddr_in {" * -nir
grep表示查找,雙引號內的東西是你要查找的內容的一部分
*表示在當前目錄下。-nir中 n表示顯示行號,i表示不區分大小寫,r表示逐行掃描
linux/in.h:232:struct sockaddr_in {
得到結果:232表示行號,linux/in.h表示所在文件夾
vi linux/in.h  +232
這個命令是直接打開定位到該文件的232行。
  • linux查看端口號占用命令-netstat
netstat -pan | grep 5623
#其中5623位端口號

在這里插入圖片描述如圖:可以看到占用該端口號的進程,并且可以利用ps指令找到程序名稱。

判斷socket有沒有與客戶端斷開連接

本文參照博客:socket編程

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

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

相關文章

【Python】Python Mako模板使用

參考資料&#xff1a; Mako Templates for Python官網&#xff1a;http://www.makotemplates.org/ Python模板庫Mako的用法&#xff1a;http://my.oschina.net/u/877170/blog/290438 Mako 1.0.4 Documentation&#xff1a;http://docs.makotemplates.org/en/latest/usage.html#…

簡單的ftp服務器(客戶端、服務器端、socket)

查看本機IP地址&#xff1a; 127.0.0.1 服務器功能&#xff1a; 可以獲取服務器文件使用get指令可以展示服務器有哪些文件使用ls指令進入服務器某個文件夾使用指令cd文件夾名稱上傳本地文件到服務器&#xff0c;使用指令putpwd可以查看客戶端在當前服務器的位置 客戶端本地…

JavaScript 全局對象

JavaScript 全局對象 全局屬性和函數可用于所有內建的 JavaScript 對象。 頂層函數&#xff08;全局函數&#xff09; 函數描述decodeURI()解碼某個編碼的 URI。decodeURIComponent()解碼一個編碼的 URI 組件。encodeURI()把字符串編碼為 URI。encodeURIComponent()把字符串編碼…

Redis持久化方式~RDB 持久化和AOF 持久化

持久化 Redis 是內存型數據庫&#xff0c;為了保證數據在斷電后不會丟失&#xff0c;需要將內存中的數據持久化到硬盤上。 RDB 持久化 將某個時間點的所有數據都存放到硬盤上。 可以將快照復制到其它服務器從而創建具有相同數據的服務器副本。 如果系統發生故障&#xff0…

Linux文件和目錄權限筆記

查看文件或者目錄的權限命令&#xff1a;ls -al # -a 表示全部文件包含隱藏文件&#xff0c;-l 表示列出每個文件的詳細信息比如執行 ls -altotal 115drwxr--x--- 4 root root 4096 Oct 24 02:07 install.log格式說明&#xff1a;通過 ls -al 格式化輸出的文件詳細信息&#x…

python基礎:序列(列表、元組、字符串)、函數、字典、集合

Python語言運行環境&#xff1a; windowslinuxunixMacos等等 博客記錄內容&#xff1a; Python3的所有語法、面向對象思維、運用模塊進行編程、游戲編程、計算機仿真。 Python是什么類型的語言&#xff1a; Python是腳本語言&#xff0c;腳本語言(Scripting language)是電腦…

Redis 與 Memcached的區別

Redis 與 Memcached 兩者都是非關系型內存鍵值數據庫&#xff0c;主要有以下不同&#xff1a; 數據類型 Memcached 僅支持字符串類型&#xff0c;而 Redis 支持五種不同的數據類型&#xff0c;可以更靈活地解決問題。 數據持久化 Redis 支持兩種持久化策略&#xff1a;RDB…

python基礎(文件、異常、模塊、類、對象)

文件&#xff1a; 打開文件使用open函數&#xff0c;open()的第一個參數是&#xff1a;要打開文件的路徑&#xff0c;如果只傳入文件名那么將在當前文件下查找文件并打開。第二個參數是&#xff1a;文件的打開模式&#xff0c;其他參數都是默認的。文件的打開模式如下圖所示&a…

redis 和 memcached 的區別

redis 和 memcached 的區別 對于 redis 和 memcached 我總結了下面四點。現在公司一般都是用 redis 來實現緩存&#xff0c;而且 redis 自身也越來越強大了&#xff01; redis支持更豐富的數據類型&#xff08;支持更復雜的應用場景&#xff09;&#xff1a;Redis不僅僅支持簡…

樹莓派入門(樹莓派登錄的幾種方式)

什么是嵌入式&#xff1f; 嵌入式即嵌入式系統&#xff0c;IEEE&#xff08;美國電氣和電子工程師協會&#xff09;對其定義是用于控制、監視或者輔助操作機器和設備的裝置&#xff0c;是一種專用的計算機系統。國內普遍認同的嵌入式系統定義是以應用為中心&#xff0c;以計算…

git 如何刪除本地創建的倉庫(轉載自 https://segmentfault.com/q/1010000002996177?_ea=262685)...

可以先清除本地文件夾下的git文件&#xff0c;然后在重新初始化新建的git倉庫 //刪除文件夾下的所有 .git 文件 find . -name ".git" | xargs rm -Rf接著add&#xff0c;commit等操作即可轉載于:https://www.cnblogs.com/xiahl/p/5289266.html

mysql中SQL查詢優化方法總結

1.對查詢進行優化&#xff0c;應盡量避免全表掃描&#xff0c;首先應考慮在 where 及 order by 涉及的列上建立索引。 2.應盡量避免在 where 子句中對字段進行 null 值判斷&#xff0c;否則將導致引擎放棄使用索引而進行全表掃描&#xff0c;如&#xff1a;select id from t w…

Linux庫概念及相關編程(動態庫、靜態庫、環境變量)

分文件編程&#xff1a; 好處&#xff1a;分模塊編程思想&#xff0c;功能和責任劃分清楚便與調試&#xff0c;main函數簡潔&#xff0c;代碼易于閱讀。編程時頭文件有的是使用<>這個符號括起來的&#xff0c;有的是" "使用的是雙引號&#xff0c;使用尖括號括…

復利計算器

import java.util.Scanner;public class Fulijisuan {public static void main(String[] args) {// TODO Auto-generated method stubdouble F0;double singlesum0;double doublesum0;double m0;Scanner scanner new Scanner(System.in);System.out.println("1:復利計算\n…

kali掃描內網ip_Metasploit路由轉發實現內網滲透

利用背景在滲透的過程中常常會遇到這種場景&#xff1a;我們已經通過web滲透拿下一臺內網服務器&#xff0c;為了進一步進行內網滲透&#xff0c;我們會利用“淪陷主機”作為跳板進行進一步的內網滲透&#xff0c;擴大戰果。現在假設的場景是此時我們已經拿下一臺內網服務器的遠…

.NET Core 3.0 中的新變化

譯者&#xff1a;楚人Leo譯文&#xff1a;http://www.cnblogs.com/leolion/p/10585834.html原文&#xff1a;https://msdn.microsoft.com/en-us/magazine/mt848631.aspx.NET Core 3.0 是 .NET Core 平臺的下一主要版本。本文回顧 .NET Core 發展歷史&#xff0c;并展示了它是如…

樹莓派GPIO口的使用(外設相關開發WringPi庫的使用,超聲波、繼電器)

樹莓派的接口&#xff1a; 大而簡單的類別&#xff1a;IO口&#xff0c;input和output是相對于主控芯片來說的&#xff0c;是根據MCU和外設之間的關系將IO口的功能分為output和input。當IO作為input使用時外設有&#xff1a;人體傳感器、煙霧傳感器、火焰傳感器、振動傳感器等…

下拉框+搜索插件

chosen 轉載于:https://www.cnblogs.com/ilikeballs/p/5291983.html

volatile指令重排_有多少人面試栽到Volatile上?面試問題都總結到這兒了

Volatile關鍵字volatile 是Java虛擬機提供的 輕量級 的同步機制.何為 輕量級 呢&#xff0c;這要相對于 synchronized 來說。Volatile有如下三個特點。要搞清楚上面列舉的名詞 可見性 原子性 指令重排 的含義我們需要首先弄清楚JMM(Java內存模型是怎么回事)JMM規定了內存主要劃…