python基礎網路編程--轉

来源:https://www.cnblogs.com/nongchaoer/archive/2019/01/10/10252653.html
-Advertisement-
Play Games

python之網路編程 本地的進程間通信(IPC)有很多種方式,但可以總結為下麵4類: 消息傳遞(管道、FIFO、消息隊列) 同步(互斥量、條件變數、讀寫鎖、文件和寫記錄鎖、信號量) 共用記憶體(匿名的和具名的) 遠程過程調用(Solaris門和Sun RPC) 但這些都不是本文的主題!我們要討論的是 ...


python之網路編程

本地的進程間通信(IPC)有很多種方式,但可以總結為下麵4類:

  • 消息傳遞(管道、FIFO、消息隊列)
  • 同步(互斥量、條件變數、讀寫鎖、文件和寫記錄鎖、信號量)
  • 共用記憶體(匿名的和具名的)
  • 遠程過程調用(Solaris門和Sun RPC)

但這些都不是本文的主題!我們要討論的是網路中進程之間如何通信?首要解決的問題是如何唯一標識一個進程,否則通信無從談起!在本地可以通過進程PID來唯一標識一個進程,但是在網路中這是行不通的。其實TCP/IP協議族已經幫我們解決了這個問題,網路層的“ip地址”可以唯一標識網路中的主機,而傳輸層的“協議+埠”可以唯一標識主機中的應用程式(進程)。這樣利用三元組(ip地址,協議,埠)就可以標識網路的進程了,網路中的進程通信就可以利用這個標誌與其它進程進行交互。

使用TCP/IP協議的應用程式通常採用應用編程介面:UNIX  BSD的套接字(socket)和UNIX System V的TLI(已經被淘汰),來實現網路進程之間的通信。就目前而言,幾乎所有的應用程式都是採用socket,而現在又是網路時代,網路中進程通信是無處不在,這就是我為什麼說“一切皆socket”。


網路通信就是兩個進程在通信

網路編程對所有開發語言都是一樣的,Python也不例外。用Python進行網路編程,就是在Python程式本身這個進程內,連接別的伺服器進程的通信埠進行通信。

 

   (1) IP、TCP和UDP
    當您編寫socket應用程式的時候,您可以在使用TCP還是使用UDP之間做出選擇。它們都有各自的優點和缺點。
    TCP是流協議,而UDP是數據報協議。換句話說,TCP在客戶機和伺服器之間建立持續的開放連接,在該連接的生命期內,位元組可以通過該連接寫出(並且保證順序正確)。然而,通過 TCP 寫出的位元組沒有內置的結構,所以需要高層協議在被傳輸的位元組流內部分隔數據記錄和欄位。
    另一方面,UDP不需要在客戶機和伺服器之間建立連接,它只是在地址之間傳輸報文。UDP的一個很好特性在於它的包是自分隔的(self-delimiting),也就是一個數據報都準確地指出它的開始和結束位置。然而,UDP的一個可能的缺點在於,它不保證包將會按順序到達,甚至根本就不保證。當然,建立在UDP之上的高層協議可能會提供握手和確認功能。
    對於理解TCP和UDP之間的區別來說,一個有用的類比就是電話呼叫和郵寄信件之間的區別。在呼叫者用鈴聲通知接收者,並且接收者拿起聽筒之前,電話呼叫不是活動的。只要沒有一方掛斷,該電話通道就保持活動,但是在通話期間,他們可以自由地想說多少就說多少。來自任何一方的談話都按臨時的順序發生。另一方面,當你發一封信的時候,郵局在投遞時既不對接收方是否存在作任何保證,也不對信件投遞將花多長時間做出有力保證。接收方可能按與信件的發送順序不同的順序接收不同的信件,並且發送方也可能在他們發送信件是交替地接收郵件。與(理想的)郵政服務不同,無法送達的信件總是被送到死信辦公室處理,而不再返回給發送。

    (2)對等方、埠、名稱和地址
    除了TCP和UDP協議以外,通信一方(客戶機或者伺服器)還需要知道的關於與之通信的對方機器的兩件事情:IP地址或者埠。IP地址是一個32位的數據值,為了人們好記,一般用圓點分開的4組數字的形式來表示,比如:64.41.64.172。埠是一個16位的數據值,通常被簡單地表示為一個小於65536的數字。大多數情況下,該值介於10到100的範圍內。一個IP地址獲取送到某台機器的一個數據包,而一個埠讓機器決定將該數據包交給哪個進程/服務(如果有的話)。這種解釋略顯簡單,但基本思路是正確的。
    上面的描述幾乎都是正確的,但它也遺漏了一些東西。大多數時候,當人們考慮Internet主機(對等方)時,我們都不會記憶諸如64.41.64.172這樣的數字,而是記憶諸如gnosis.cx這樣的名稱。為了找到與某個特定主機名稱相關聯的IP地址,一般都使用功能變數名稱伺服器(DNS),但是有時會首先使用本地查找(經常是通過/etc/hosts的內容)。對於本教程,我們將一般地假設有一個IP地址可用,不過下麵討論編寫名稱查找代碼。

    (3)主機名稱解析
    命令行實用程式nslookup可以被用來根據符號名稱查找主機IP地址。實際上,許多常見的實用程式,比如ping或者網路配置工具,也會順便做同樣的事情。但是以編程方式做這樣的事情很簡單。

======================TCP/IP======================
應用層: 它只負責產生相應格式的數據 ssh ftp nfs cifs dns http smtp pop3
-----------------------------------
傳輸層: 定義數據傳輸的兩種模式:
TCP(傳輸控制協議:面向連接,可靠的,效率相對不高)
UDP(用戶數據報協議:非面向連接,不可靠的,但效率高)
-----------------------------------
網路層: 連接不同的網路如乙太網、令牌環網
IP (路由,分片) 、ICMP、 IGMP
ARP ( 地址解析協議,作用是將IP解析成MAC )
-----------------------------------
數據鏈路層: 乙太網傳輸
-----------------------------------
物理層: 主要任務是規定各種傳輸介質和介面與傳輸信號相關的一些特性
-----------------------------------



TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協議/網間協議,是一個工業標準的協議集,它是為廣域網(WANs)設計的。

TCP socket 由於在通向前需要建立連接,所以其模式較 UDP socket 負責些。

 

 

UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是屬於TCP/IP協議族中的一種。如圖:




UDP Socket圖:

 

UDP socket server 端代碼在進行bind後,無需調用listen方法。

TCP/IP協議族包括運輸層、網路層、鏈路層,
而socket所在位置如圖,Socket是應用層與TCP/IP協議族通信的中間軟體抽象層。


 

Socket是什麼

 

socket起源於Unix,而Unix/Linux基本哲學之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關閉close”模式來操作。Socket就是該模式的一個實現,socket即是一種特殊的文件,一些socket函數就是對其進行的操作(讀/寫IO、打開、關閉).
說白了Socket是應用層與TCP/IP協議族通信的中間軟體抽象層,它是一組介面。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket介面後面,對用戶來說,一組簡單的介面就是全部,讓Socket去組織數據,以符合指定的協議。

 

註意:其實socket也沒有層的概念,它只是一個facade設計模式的應用,讓編程變的更簡單。是一個軟體抽象層。在網路編程中,我們大量用的都是通過socket實現的。

Socket是網路編程的一個抽象概念。通常我們用一個Socket表示“打開了一個網路鏈接”,而打開一個Socket需要知道目標電腦的IP地址和埠號,再指定協議類型即可。

http://images2015.cnblogs.com/blog/720333/201611/720333-20161126215744846-706023541.png

TCP編程

Socket是網路編程的一個抽象概念。通常我們用一個Socket表示“打開了一個網路鏈接”,而打開一個Socket需要知道目標電腦的IP地址和埠號,再指定協議類型即可。 TCP連接簡圖: 三次握手,數據傳輸,四次揮手

socket中TCP的三次握手建立連接詳解

我們知道tcp建立連接要進行“三次握手”,即交換三個分組。大致流程如下:

  • 客戶端向伺服器發送一個SYN J
  • 伺服器向客戶端響應一個SYN K,並對SYN J進行確認ACK J+1
  • 客戶端再想伺服器發一個確認ACK K+1

只有就完了三次握手,但是這個三次握手發生在socket的那幾個函數中呢?請看下圖:

image

圖1、socket中發送的TCP三次握手

從圖中可以看出,當客戶端調用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返回,至此三次握手完畢,連接建立。

總結:客戶端的connect在三次握手的第二個次返回,而伺服器端的accept在三次握手的第三次返回。

5、socket中TCP的四次握手釋放連接詳解

上面介紹了socket中TCP的三次握手建立過程,及其涉及的socket函數。現在我們介紹socket中的四次握手釋放連接的過程,請看下圖:

image

圖2、socket中發送的TCP四次握手

圖示過程如下:

  • 某個應用進程首先調用close主動關閉連接,這時TCP發送一個FIN M;
  • 另一端接收到FIN M之後,執行被動關閉,對這個FIN進行確認。它的接收也作為文件結束符傳遞給應用進程,因為FIN的接收意味著應用進程在相應的連接上再也接收不到額外數據;
  • 一段時間之後,接收到文件結束符的應用進程調用close關閉它的socket。這導致它的TCP也發送一個FIN N;
  • 接收到這個FIN的源發送端TCP對它進行確認。

這樣每個方向上都有一個FIN和ACK。

Python3 網路編程

Python 提供了兩個級別訪問的網路服務。:

  • 低級別的網路服務支持基本的 Socket,它提供了標準的 BSD Sockets API,可以訪問底層操作系統Socket介面的全部方法。
  • 高級別的網路服務模塊 SocketServer, 它提供了伺服器中心類,可以簡化網路伺服器的開發。

什麼是 Socket?

Socket又稱"套接字",應用程式通常通過"套接字"向網路發出請求或者應答網路請求,使主機間或者一臺電腦上的進程間可以通訊。

socket和file的區別:

  • file模塊是針對某個指定文件進行【打開】【讀寫】【關閉】
  • socket模塊是針對 伺服器端 和 客戶端Socket 進行【打開】【讀寫】【關閉】

 

 伺服器端先初始化Socket,然後與埠綁定(bind),對埠進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然後連接伺服器(connect),如果連接成功,這時客戶端與伺服器端的連接就建立了。客戶端發送數據請求,伺服器端接收請求並處理請求,然後把回應數據發送給客戶端,客戶端讀取數據,最後關閉連接,一次交互結束。


socket()函數

Python 中,我們用 socket()函數來創建套接字,語法格式如下:

1 socket.socket([family[, type[, proto]]])

參數

  • family: 套接字家族可以使AF_UNIX或者AF_INET
  • type: 套接字類型可以根據是面向連接的還是非連接分為SOCK_STREAMSOCK_DGRAM
  • protocol: 一般不填預設為0.

簡單實例

服務端

我們使用 socket 模塊的 socket 函數來創建一個 socket 對象。socket 對象可以通過調用其他函數來設置一個 socket 服務。

現在我們可以通過調用 bind(hostname, port) 函數來指定服務的 port(埠)

接著,我們調用 socket 對象的 accept 方法。該方法等待客戶端的連接,並返回 connection 對象,表示已連接到客戶端。

完整代碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #!/usr/bin/python3 # 文件名:server.py   # 導入 socket、sys 模塊 import socket import sys   # 創建 socket 對象 serversocket = socket.socket(             socket.AF_INET, socket.SOCK_STREAM)   # 獲取本地主機名 host = socket.gethostname()   port = 9999   # 綁定埠 serversocket.bind((host, port))   # 設置最大連接數,超過後排隊 serversocket.listen(5)   while True:     # 建立客戶端連接     clientsocket,addr = serversocket.accept()            print("連接地址: %s" % str(addr))           msg='歡迎訪問python教程!'+ "\r\n"     clientsocket.send(msg.encode('utf-8'))     clientsocket.close()

 

客戶端

接下來我們寫一個簡單的客戶端實例連接到以上創建的服務。埠號為 12345。

socket.connect(hosname, port ) 方法打開一個 TCP 連接到主機為 hostname 埠為 port 的服務商。連接後我們就可以從服務端後期數據,記住,操作完成後需要關閉連接。

完整代碼如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #!/usr/bin/python3 # 文件名:client.py   # 導入 socket、sys 模塊 import socket import sys   # 創建 socket 對象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 獲取本地主機名 host = socket.gethostname()   # 設置埠好 port = 9999   # 連接服務,指定主機和埠 s.connect((host, port))   # 接收小於 1024 位元組的數據 msg = s.recv(1024)   s.close()   print (msg.decode('utf-8'))

 先執行server端,然後打開client端就能看到結果

 

客戶端

大多數連接都是可靠的TCP連接。創建TCP連接時,主動發起連接的叫客戶端,被動響應連接的叫伺服器。

舉個例子,當我們在瀏覽器中訪問新浪時,我們自己的電腦就是客戶端,瀏覽器會主動向新浪的伺服器發起連接。如果一切順利,新浪的伺服器接受了我們的連接,一個TCP連接就建立起來的,後面的通信就是發送網頁內容了。

所以,我們要創建一個基於TCP連接的Socket,可以這樣做:

1 2 3 4 5 6 7 # 導入socket庫: import socket   # 創建一個socket: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立連接: s.connect(('www.sina.com.cn', 80))

 

創建Socket時,AF_INET指定使用IPv4協議,如果要用更先進的IPv6,就指定為AF_INET6SOCK_STREAM指定使用面向流的TCP協議,這樣,一個Socket對象就創建成功,但是還沒有建立連接。

客戶端要主動發起TCP連接,必須知道伺服器的IP地址和埠號。新浪網站的IP地址可以用功能變數名稱www.sina.com.cn自動轉換到IP地址,但是怎麼知道新浪伺服器的埠號呢?

答案是作為伺服器,提供什麼樣的服務,埠號就必須固定下來。由於我們想要訪問網頁,因此新浪提供網頁服務的伺服器必須把埠號固定在80埠,因為80埠是Web服務的標準埠。其他服務都有對應的標準埠號,例如SMTP服務是25埠,FTP服務是21埠,等等。埠號小於1024的是Internet標準服務的埠,埠號大於1024的,可以任意使用。

因此,我們連接新浪伺服器的代碼如下:

1 s.connect(('www.sina.com.cn', 80))

 

註意參數是一個tuple,包含地址和埠號。

建立TCP連接後,我們就可以向新浪伺服器發送請求,要求返迴首頁的內容:

1 2 # 發送數據: s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')

 

TCP連接創建的是雙向通道,雙方都可以同時給對方發數據。但是誰先發誰後發,怎麼協調,要根據具體的協議來決定。例如,HTTP協議規定客戶端必須先發請求給伺服器,伺服器收到後才發數據給客戶端。

發送的文本格式必須符合HTTP標準,如果格式沒問題,接下來就可以接收新浪伺服器返回的數據了:

接收數據時,調用recv(max)方法,一次最多接收指定的位元組數,因此,在一個while迴圈中反覆接收,直到recv()返回空數據,表示接收完畢,退出迴圈。

當我們接收完數據後,調用close()方法關閉Socket,這樣,一次完整的網路通信就結束了:

1 2 # 關閉連接: s.close()

 

接收到的數據包括HTTP頭和網頁本身,我們只需要把HTTP頭和網頁分離一下,把HTTP頭列印出來,網頁內容保存到文件:

1 2 3 4 5 header, html = data.split(b'\r\n\r\n', 1) print(header.decode('utf-8')) # 把接收的數據寫入文件: with open('sina.html', 'wb') as f:     f.write(html)

 

現在,只需要在瀏覽器中打開這個sina.html文件,就可以看到新浪的首頁了。

伺服器

和客戶端編程相比,伺服器編程就要複雜一些。

伺服器進程首先要綁定一個埠並監聽來自其他客戶端的連接。如果某個客戶端連接過來了,伺服器就與該客戶端建立Socket連接,隨後的通信就靠這個Socket連接了。

所以,伺服器會打開固定埠(比如80)監聽,每來一個客戶端連接,就創建該Socket連接。由於伺服器會有大量來自客戶端的連接,所以,伺服器要能夠區分一個Socket連接是和哪個客戶端綁定的。一個Socket依賴4項:伺服器地址、伺服器埠、客戶端地址、客戶端埠來唯一確定一個Socket。

但是伺服器還需要同時響應多個客戶端的請求,所以,每個連接都需要一個新的進程或者新的線程來處理,否則,伺服器一次就只能服務一個客戶端了。

我們來編寫一個簡單的伺服器程式,它接收客戶端連接,把客戶端發過來的字元串加上Hello再發回去。

首先,創建一個基於IPv4和TCP協議的Socket:

1 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

然後,我們要綁定監聽的地址和埠。伺服器可能有多塊網卡,可以綁定到某一塊網卡的IP地址上,也可以用0.0.0.0綁定到所有的網路地址,還可以用127.0.0.1綁定到本機地址。127.0.0.1是一個特殊的IP地址,表示本機地址,如果綁定到這個地址,客戶端必須同時在本機運行才能連接,也就是說,外部的電腦無法連接進來。

埠號需要預先指定。因為我們寫的這個服務不是標準服務,所以用9999這個埠號。請註意,小於1024的埠號必須要有管理員許可權才能綁定:

1 2 # 監聽埠: s.bind(('127.0.0.1', 9999))

 

緊接著,調用listen()方法開始監聽埠,傳入的參數指定等待連接的最大數量:

1 2 s.listen(5) print('Waiting for connection...')

 

接下來,伺服器程式通過一個永久迴圈來接受來自客戶端的連接,accept()會等待並返回一個客戶端的連接:

1 2 3 4 5 6 while True:     # 接受一個新連接:     sock, addr = s.accept()     # 創建新線程來處理TCP連接:     t = threading.Thread(target=tcplink, args=(sock, addr))     t.start()

 

每個連接都必須創建新線程(或進程)來處理,否則,單線程在處理連接的過程中,無法接受其他客戶端的連接:

1 2 3 4 5 6 7 8 9 10 11 def tcplink(sock, addr):     print('Accept new connection from %s:%s...' % addr)     sock.send(b'Welcome!')     while True:         data = sock.recv(1024)         time.sleep(1)         if not data or data.decode('utf-8') == 'exit':             break         sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))     sock.close()     print('Connection from %s:%s closed.' % addr)

 

連接建立後,伺服器首先發一條歡迎消息,然後等待客戶端數據,並加上Hello再發送給客戶端。如果客戶端發送了exit字元串,就直接關閉連接。

要測試這個伺服器程式,我們還需要編寫一個客戶端程式:

1 2 3 4 5 6 7 8 9 10 11 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立連接: s.connect(('127.0.0.1', 9999)) # 接收歡迎消息: print(s.recv(1024).decode('utf-8')) for data in [b'Michael', b'Tracy', b'Sarah']:     # 發送數據:     s.send(data)     print(s.recv(1024).decode('utf-8')) s.send(b'exit') s.close()

 

我們需要打開兩個命令行視窗,一個運行伺服器程式,另一個運行客戶端程式,就可以看到效果了:

UDP編程

TCP是建立可靠連接,並且通信雙方都可以以流的形式發送數據。相對TCP,UDP則是面向無連接的協議。

使用UDP協議時,不需要建立連接,只需要知道對方的IP地址和埠號,就可以直接發數據包。但是,能不能到達就不知道了。

雖然用UDP傳輸數據不可靠,但它的優點是和TCP比,速度快,對於不要求可靠到達的數據,就可以使用UDP協議。

我們來看看如何通過UDP協議傳輸數據。和TCP類似,使用UDP的通信雙方也分為客戶端和伺服器。伺服器首先需要綁定埠:

1 2 3 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 綁定埠: s.bind(('127.0.0.1', 9999))

 

創建Socket時,SOCK_DGRAM指定了這個Socket的類型是UDP。綁定埠和TCP一樣,但是不需要調用listen()方法,而是直接接收來自任何客戶端的數據:

1 2 3 4 5 6 print 'Bind UDP on 9999...' while True:     # 接收數據:     data, addr = s.recvfrom(1024)     print 'Received from %s:%s.' % addr     s.sendto('Hello, %s!' % data, addr)

 

recvfrom()方法返回數據和客戶端的地址與埠,這樣,伺服器收到數據後,直接調用sendto()就可以把數據用UDP發給客戶端。

註意這裡省掉了多線程,因為這個例子很簡單。

客戶端使用UDP時,首先仍然創建基於UDP的Socket,然後,不需要調用connect(),直接通過sendto()給伺服器發數據:

1 2 3 4 5 6 7 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for data in ['Michael', 'Tracy', 'Sarah']:     # 發送數據:     s.sendto(data, ('127.0.0.1', 9999))     # 接收數據:     print s.recv(1024) s.close()

 

從伺服器接收數據仍然調用recv()方法。

小結

UDP的使用與TCP類似,但是不需要建立連接。此外,伺服器綁定UDP埠和TCP埠互不衝突,也就是說,UDP的9999埠與TCP的9999埠可以各自綁定。

 

Python 提供了兩個級別訪問的網路服務。:

  • 低級別的網路服務支持基本的 Socket,它提供了標準的 BSD Sockets API,可以訪問底層操作系統Socket介面的全部方法。
  • 高級別的網路服務模塊 SocketServer, 它提供了伺服器中心類,可以簡化網路伺服器的開發。

 

Socket 對象(內建)方法

函數描述
伺服器端套接字
s.bind() 綁定地址(host,port)到套接字, 在AF_INET下,以元組(host,port)的形式表示地址。
s.listen() 開始TCP監聽。backlog指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少為1,大部分應用程式設為5就可以了。
s.accept() 被動接受TCP客戶端連接,(阻塞式)等待連接的到來
客戶端套接字
s.connect() 主動初始化TCP伺服器連接,。一般address的格式為元組(hostname,port),如果連接出錯,返回socket.error錯誤。
s.connect_ex() connect()函數的擴展版本,出錯時返回出錯碼,而不是拋出異常
公共用途的套接字函數
s.recv() 接收TCP數據,數據以字元串形式返回,bufsize指定要接收的最大數據量。flag提供有關消息的其他信息,通常可以忽略。
s.send() 發送TCP數據,將string中的數據發送到連接的套接字。返回值是要發送的位元組數量,該數量可能
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題:在上一篇 "繼承與多態 文本查詢的小例子(智能指針版本)" 在Query類里使用的是智能指針,只把智能指針換成普通的指針,並不添加拷貝構造方法,會發生什麼呢? 執行時,代碼崩掉。 分析下麵一行代碼: 1,首先調用Query(string)的構造函數,把Query的成員q指向了new WordQ ...
  • 看了一個垃圾程式的架構,mmp真坑,自己費了一點功夫才搞定,就直接記錄下吧,這個是windows簡單的應用程式,但是裡面有點複雜,我們需要首先建立一個基於mfc的appwinzard程式,(憑記憶寫的,不知道單詞有沒有錯誤),然後我們直接在winmain類中添加下麵的變數# include# def... ...
  • 一、開始: 下載地址:http://nodejs.cn/download/ 下載安裝: 直到 二、打開CMD,檢查是否正常 在安裝目錄里新增兩個文件夾 然後運行命令:如下圖: npm config set prefix "D:\InstallSoftWare\nodejs\node_global" ...
  • 為了更好的理解繼承和多態,做一個文本查詢的小例子。 介面類:Query有2個方法。 eval:查詢,返回查詢結果類QueryResult rep:得到要查詢的文本 客戶端程式的使用方法: 介面類:Query,有一個私有的父類Query_base的智能指針。 父類Query_base有子類WordQu ...
  • 上一篇博客講了進程、線程、協程和GIL的基本概念,這篇我們來說說在以下三點: 1> python中使用threading庫來創建線程的兩種方式 2> 使用Event對消來判斷線程是否已啟動 3> 使用Semaphore和BoundedSemaphore兩個類分別來控制線程的併發數以及二者之間的區別。 ...
  • 一、什麼是函數 當我們在日常工作中編寫代碼時,有沒有發現這種情況,寫了一套代碼,卻發現裡面有很多段代碼出現了有規律的重覆,這樣就不符合一個合格程式員的標準了,一個合格的程式員編寫的代碼最重要的應該是簡潔,精煉。那麼,有什麼方法能減少代碼中出現的這樣有規律的重覆的情況嗎?當然有,那就是函數。例如我們平 ...
  • Django自帶後臺管理的配置 創建項目和應用 修改配置文件 資料庫配置 應用配置 時間和語言相關配置 當前應用的models下創建類 生成遷移文件 python manage.py makemigrations 執行遷移 pythin manage.py migrate 啟動項目 啟動項目 訪問 ...
  • 模塊:本質就是.py結尾的文件。從邏輯上組織python代碼。 包: 本質就是一個目錄,帶有__init__.py文件,從邏輯上組織模塊。 模塊的分類: 1.標準庫(內置的模塊) 2.開源庫(第三方庫) 3.自定義模塊 模塊導入方法: 1.import + 模塊名 2.from......impor ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...