亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Golang TCP網(wǎng)絡(luò)編程的具體實(shí)現(xiàn)

 更新時間:2024年06月13日 09:34:25   作者:2021dragon  
go語言是一門功能強(qiáng)大的編程語言,它提供了眾多的網(wǎng)絡(luò)編程庫,其中包括tcp/ip,本文主要介紹了Golang TCP網(wǎng)絡(luò)編程的具體實(shí)現(xiàn),具有一定的參考價值,感興趣的可以來了解一下

網(wǎng)絡(luò)編程介紹

網(wǎng)絡(luò)編程介紹

  • 網(wǎng)絡(luò)編程是指通過計(jì)算機(jī)網(wǎng)絡(luò)實(shí)現(xiàn)程序間通信的一種編程技術(shù),涉及到在不同計(jì)算機(jī)之間建立連接、傳輸數(shù)據(jù)和協(xié)議解析等操作。
  • 套接字(Socket)編程是網(wǎng)絡(luò)編程的一種實(shí)現(xiàn)方式,其提供了一種機(jī)制,使得應(yīng)用程序能夠通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)傳輸和通信。
  • Go中的net包是標(biāo)準(zhǔn)庫中提供的網(wǎng)絡(luò)編程包,是基于套接字編程的一種實(shí)現(xiàn)方式,提供了對TCP、UDP、IP、ICMP、Unix域套接字等常見網(wǎng)絡(luò)協(xié)議的支持,通過net包可以完成創(chuàng)建套接字、建立連接、發(fā)送和接收數(shù)據(jù)等操作,實(shí)現(xiàn)網(wǎng)絡(luò)通信。

TCP網(wǎng)絡(luò)編程

服務(wù)器監(jiān)聽

服務(wù)器監(jiān)聽

在Go的net包中,Listen函數(shù)用于創(chuàng)建并返回一個網(wǎng)絡(luò)監(jiān)聽器(Listener),以監(jiān)聽指定網(wǎng)絡(luò)地址和端口上的連接請求。該函數(shù)的函數(shù)原型如下:

func Listen(network, address string) (Listener, error)

參數(shù)說明:

  • network:用于指定網(wǎng)絡(luò)類型,其值必須是"tcp", “tcp4”, “tcp6”, “unix"或"unixpacket”。
  • address:用于指定需要被監(jiān)聽的IP地址和端口號,格式為"host:port"。

返回值說明:

  • 第一個返回值:表示創(chuàng)建的網(wǎng)絡(luò)監(jiān)聽器。
  • 第二個返回值:如果創(chuàng)建網(wǎng)絡(luò)監(jiān)聽器過程中出錯,將返回非nil的錯誤值。

通過Listen函數(shù)創(chuàng)建得到的網(wǎng)絡(luò)監(jiān)聽器是Listener類型的,該類型是一個接口類型,其定義如下:

type Listener interface {
	// Accept waits for and returns the next connection to the listener.
	Accept() (Conn, error)

	// Close closes the listener.
	// Any blocked Accept operations will be unblocked and return errors.
	Close() error

	// Addr returns the listener's network address.
	Addr() Addr
}

Listener接口中各方法說明:

  • Accept方法:從底層獲取下一個已經(jīng)建立好的連接給監(jiān)聽器。
  • Close方法:關(guān)閉監(jiān)聽器。
  • Addr方法:返回監(jiān)聽器對應(yīng)的網(wǎng)絡(luò)地址(由IP地址和端口號組成)。

當(dāng)使用Listen函數(shù)創(chuàng)建TCP類型的監(jiān)聽器時,其返回的監(jiān)聽器底層具體的類型是TCPListener,其定義如下:

type TCPListener struct {
	fd *netFD
	lc ListenConfig
}

TCPListener結(jié)構(gòu)體各字段說明:

  • fd:對底層網(wǎng)絡(luò)文件描述符的封裝,提供了對網(wǎng)絡(luò)連接的讀寫和控制操作。
  • lc:用于配置監(jiān)聽器創(chuàng)建的行為,比如設(shè)置監(jiān)聽地址、控制網(wǎng)絡(luò)參數(shù)等。

TCPListener結(jié)構(gòu)體中的fd字段是netFD類型的,其定義如下:

type netFD struct {
	pfd poll.FD

	// immutable until Close
	family      int
	sotype      int
	isConnected bool // handshake completed or use of association with peer
	net         string
	laddr       Addr
	raddr       Addr
}

netFD結(jié)構(gòu)體各字段說明:

  • pfd:用于與底層的操作系統(tǒng)文件描述符進(jìn)行交互。
  • family:表示套接字的協(xié)議家族,比如IPv4或IPv6。
  • sotype:表示套接字的類型,比如TCP或UDP
  • isConnected:表示連接是否已完成握手或與對方建立關(guān)聯(lián)。
  • net:表示網(wǎng)絡(luò)協(xié)議,比如"tcp"或"udp"。
  • laddr:表示本地網(wǎng)絡(luò)連接的地址。
  • raddr:表示遠(yuǎn)程網(wǎng)絡(luò)連接的地址。

服務(wù)器監(jiān)聽示例

服務(wù)器監(jiān)聽示例如下:

package main

import (
	"fmt"
	"net"
)

func main() {
	// 服務(wù)器監(jiān)聽
	listen, err := net.Listen("tcp", "0.0.0.0:8081")
	if err != nil {
		fmt.Printf("listen error, err = %v\n", err)
		return
	}
	defer listen.Close()
	fmt.Println("listen success...")
}

說明一下:

  • 服務(wù)器在創(chuàng)建監(jiān)聽套接字時,將其綁定到0.0.0.0(通常表示為INADDR_ANY)地址,這樣服務(wù)器就可以同時監(jiān)聽和接受來自不同網(wǎng)絡(luò)接口的連接請求,而不需要為每個接口分別創(chuàng)建監(jiān)聽套接字。
  • 為了避免網(wǎng)絡(luò)文件描述符資源泄露,在創(chuàng)建監(jiān)聽器后及時利用defer機(jī)制關(guān)閉監(jiān)聽器。監(jiān)聽器被關(guān)閉后會停止監(jiān)聽新的連接請求,并且任何被阻塞的Accept操作都會被解除阻塞并返回錯誤。

客戶端連接服務(wù)器

客戶端連接服務(wù)器

在Go的net包中,Dial函數(shù)用于客戶端應(yīng)用程序與遠(yuǎn)程服務(wù)器建立連接。該函數(shù)的函數(shù)原型如下:

func Dial(network, address string) (Conn, error)

參數(shù)說明:

  • network:用于指定網(wǎng)絡(luò)協(xié)議,比如"tcp", "udp"等。
  • address:用于指定連接的目標(biāo)地址。

返回值說明:

  • 第一個返回值:表示建立的網(wǎng)絡(luò)連接。
  • 第二個返回值:如果建立網(wǎng)絡(luò)連接過程中出錯,將返回非nil的錯誤值。

通過Dial函數(shù)建立得到的連接Conn類型的,該類型是一個接口類型,其定義如下:

type Conn interface {
	// Read reads data from the connection.
	Read(b []byte) (n int, err error)

	// Write writes data to the connection.
	Write(b []byte) (n int, err error)

	// Close closes the connection.
	// Any blocked Read or Write operations will be unblocked and return errors.
	Close() error

	// LocalAddr returns the local network address, if known.
	LocalAddr() Addr

	// RemoteAddr returns the remote network address, if known.
	RemoteAddr() Addr

	// SetDeadline sets the read and write deadlines associated
	// with the connection. It is equivalent to calling both
	// SetReadDeadline and SetWriteDeadline.
	SetDeadline(t time.Time) error

	// SetReadDeadline sets the deadline for future Read calls
	// and any currently-blocked Read call.
	SetReadDeadline(t time.Time) error

	// SetWriteDeadline sets the deadline for future Write calls
	// and any currently-blocked Write call.
	SetWriteDeadline(t time.Time) error
}

Conn接口中各方法說明:

  • Read方法:從連接中讀取數(shù)據(jù)。
  • Write方法:向連接中寫入數(shù)據(jù)。
  • Close方法:關(guān)閉連接。
  • LocalAddr方法:返回連接對應(yīng)的本地網(wǎng)絡(luò)地址(由IP地址和端口號組成)。
  • RemoteAddr方法:返回連接對應(yīng)的遠(yuǎn)程網(wǎng)絡(luò)地址(由IP地址和端口號組成)。
  • SetDeadline方法:設(shè)置連接讀取和寫入的截止時間。
  • SetReadDeadline方法:設(shè)置連接讀取的截止時間。
  • SetWriteDeadline方法:設(shè)置連接寫入的截止時間。

當(dāng)使用Dial函數(shù)與TCP服務(wù)器建立連接時,其返回的網(wǎng)絡(luò)連接底層具體的類型是TCPConn,其定義如下:

type TCPConn struct {
	conn
}

TCPConn結(jié)構(gòu)體中僅嵌套了一個conn類型的匿名結(jié)構(gòu)體,其定義如下:

type conn struct {
	fd *netFD
}

可以看到,conn結(jié)構(gòu)體中的fd字段與TCPListener結(jié)構(gòu)體中的fd字段的類型相同,它們都是對底層網(wǎng)絡(luò)文件描述符的封裝,提供了對網(wǎng)絡(luò)連接的讀寫和控制操作。

客戶端連接服務(wù)器示例

客戶端連接服務(wù)器示例如下:

package main

import (
	"fmt"
	"net"
)

func main() {
	// 客戶端連接服務(wù)器
	conn, err := net.Dial("tcp", "127.0.0.1:8081")
	if err != nil {
		fmt.Printf("connect server error, err = %v\n", err)
		return
	}
	defer conn.Close()
	fmt.Println("connect server success...")
}

說明一下:

  • 當(dāng)客戶端連接TCP服務(wù)器時,服務(wù)器必須處于監(jiān)聽狀態(tài)。
  • 為了避免網(wǎng)絡(luò)文件描述符資源泄露,客戶端在與服務(wù)器建立連接后及時利用defer機(jī)制關(guān)閉連接。

服務(wù)端獲取連接

服務(wù)端獲取連接

在創(chuàng)建TCP網(wǎng)絡(luò)監(jiān)聽器后,調(diào)用Listener接口的Accept方法,本質(zhì)調(diào)用的是TCPListener的Accept方法,該方法用于從底層獲取下一個已經(jīng)建立好的連接給監(jiān)聽器,如果底層沒有建立好的連接則會進(jìn)行阻塞等待。該方法的原型如下:

func (l *TCPListener) Accept() (Conn, error)

返回值說明:

  • 第一個返回值:表示獲取到的與客戶端建立好的連接。
  • 第二個返回值:如果在獲取連接過程中出錯,將返回非nil的錯誤值。

服務(wù)端獲取連接示例

服務(wù)端獲取連接示例如下:

package main

import (
	"fmt"
	"net"
)

func process(conn net.Conn) {
	defer conn.Close()

	fmt.Printf("handle a link %v...\n", conn.RemoteAddr())
}

func main() {
	// 服務(wù)器監(jiān)聽
	listen, err := net.Listen("tcp", "0.0.0.0:8081")
	if err != nil {
		fmt.Printf("listen error, err = %v\n", err)
		return
	}
	defer listen.Close()
	fmt.Println("listen success...")

	for {
		fmt.Println("waiting client connect...")
		// 服務(wù)端獲取連接
		conn, err := listen.Accept()
		if err != nil {
			fmt.Printf("accept error, err = %v\n", err)
			continue
		}
		fmt.Printf("get a link from %v...\n", conn.RemoteAddr())
		// 開啟新協(xié)程為客戶端提供服務(wù)
		go process(conn)
	}
}

說明一下:

  • 網(wǎng)絡(luò)監(jiān)聽器的任務(wù)就是不斷調(diào)用Accept方法,從底層獲取已經(jīng)建立好的連接并為其提供服務(wù),通常在獲取到一個連接后會開啟一個新協(xié)程為其提供服務(wù),而主協(xié)程則繼續(xù)調(diào)用Accept方法獲取新的連接。
  • 為了讓新協(xié)程能夠獲取需要被處理的連接,需要將對應(yīng)的連接通過參數(shù)傳遞的方式,傳遞給協(xié)程對應(yīng)的處理函數(shù)。此外,為了避免網(wǎng)絡(luò)文件描述符資源泄露,需要在處理函數(shù)中利用defer機(jī)制關(guān)閉連接,保證連接處理完畢后能夠及時關(guān)閉連接。

向連接中寫入數(shù)據(jù)

向連接中寫入數(shù)據(jù)

在創(chuàng)建TCP連接后,調(diào)用Conn接口的Write方法,本質(zhì)調(diào)用的是TCPConn的Write方法,該方法用于向連接中寫入數(shù)據(jù)。該方法的原型如下:

func (c *TCPConn) Write(b []byte) (int, error)

參數(shù)說明:

  • b:表示要寫入連接的數(shù)據(jù)。

返回值說明:

  • 第一個返回值:表示實(shí)際寫入的字節(jié)數(shù)。
  • 第二個返回值:如果在寫入數(shù)據(jù)過程中出錯,將返回非nil的錯誤值。

從連接中讀取數(shù)據(jù)

從連接中讀取數(shù)據(jù)

在創(chuàng)建TCP連接后,調(diào)用Conn接口的Read方法,本質(zhì)調(diào)用的是TCPConn的Read方法,該方法用于從連接中讀取數(shù)據(jù)。該方法的原型如下:

func (c *TCPConn) Read(b []byte) (int, error)

參數(shù)說明:

  • b:輸出型參數(shù),用于存儲讀取到的數(shù)據(jù)。

返回值說明:

  • 第一個返回值:表示實(shí)際讀取的字節(jié)數(shù)。
  • 第二個返回值:如果在讀取數(shù)據(jù)過程中出錯,將返回非nil的錯誤值。

關(guān)閉連接/監(jiān)聽器

關(guān)閉連接/監(jiān)聽器

為了避免網(wǎng)絡(luò)文件描述符泄露,TCP網(wǎng)絡(luò)監(jiān)聽器和TCP連接在使用完畢后都需要及時將其關(guān)閉,對應(yīng)調(diào)用的分別是TCPListener和TCPConn的Close方法,這兩個方法的原型如下:

func (l *TCPListener) Close() error
func (c *TCPConn) Close() error

返回值說明:

  • 如果在關(guān)閉監(jiān)聽器或關(guān)閉連接過程中出錯,將返回非nil的錯誤值。

簡易的TCP回聲服務(wù)器

效果展示

效果展示

為了演示使用net包實(shí)現(xiàn)網(wǎng)絡(luò)通信,下面實(shí)現(xiàn)了一個簡易的TCP回聲服務(wù)器,其功能如下:

  • 服務(wù)端能夠同時處理多個客戶端的連接請求,在為每個客戶端提供服務(wù)時,能夠?qū)⒏鱾€客戶端發(fā)來的數(shù)據(jù)顯示在服務(wù)端,同時將客戶端發(fā)來的數(shù)據(jù)再發(fā)回給客戶端。
  • 客戶端在連接到服務(wù)器后,能夠不斷從控制臺讀取用戶輸入的數(shù)據(jù)發(fā)送給服務(wù)端,并將服務(wù)端發(fā)來的數(shù)據(jù)顯示在客戶端,用戶在控制臺輸入exit能夠退出客戶端。

最終效果如下:

在這里插入圖片描述

服務(wù)端處理邏輯

服務(wù)端處理邏輯

服務(wù)端處理邏輯如下:

  • 主協(xié)程調(diào)用Listen函數(shù)完成服務(wù)器的監(jiān)聽后,通過監(jiān)聽器不斷調(diào)用Accept方法從底層獲取已經(jīng)建立好的連接,并為每一個獲取到的連接創(chuàng)建一個新協(xié)程為其提供服務(wù),而主協(xié)程則繼續(xù)獲取新的連接。
  • 每個新協(xié)程在為其對應(yīng)的連接提供服務(wù)時,通過調(diào)用連接的Read方法不斷讀取客戶端發(fā)來的數(shù)據(jù),將數(shù)據(jù)其顯示在服務(wù)端,同時通過調(diào)用連接的Write方法將客戶端發(fā)來的數(shù)據(jù)再發(fā)回給客戶端。
  • 每個新協(xié)程在為其對應(yīng)的連接提供服務(wù)的過程中,如果從連接中讀取數(shù)據(jù)或向連接中寫入數(shù)據(jù)時出錯,或是客戶端退出,則通過調(diào)用連接的Close方法將對應(yīng)的連接關(guān)閉。

服務(wù)端代碼如下:

package main

import (
	"fmt"
	"io"
	"net"
)

func process(conn net.Conn) {
	defer conn.Close()

	data := make([]byte, 1024)
	for {
		// 1、讀取客戶端發(fā)來的數(shù)據(jù)
		n, err := conn.Read(data)
		if err != nil {
			if err == io.EOF {
				fmt.Printf("client %v quit\n", conn.RemoteAddr())
			} else {
				fmt.Printf("read client message error, err = %v\n", err)
			}
			return
		}
		fmt.Printf("client message[%v]: %v\n", conn.RemoteAddr(), string(data[:n]))

		// 2、發(fā)送數(shù)據(jù)給客戶端
		len, err := conn.Write(data[:n])
		if err != nil || len != n {
			fmt.Printf("send back message error, err = %v\n", err)
			return
		}
	}
}

func main() {
	// 服務(wù)器監(jiān)聽
	listen, err := net.Listen("tcp", "0.0.0.0:8081")
	if err != nil {
		fmt.Printf("listen error, err = %v\n", err)
		return
	}
	defer listen.Close()
	fmt.Println("listen success...")

	for {
		fmt.Println("waiting client connect...")
		// 服務(wù)端獲取連接
		conn, err := listen.Accept()
		if err != nil {
			fmt.Printf("accept error, err = %v\n", err)
			continue
		}
		fmt.Printf("get a link from %v...\n", conn.RemoteAddr())
		// 開啟新協(xié)程為客戶端提供服務(wù)
		go process(conn)
	}
}

說明一下:

  • 當(dāng)服務(wù)端從某個連接中讀取數(shù)據(jù)時,如果該連接對應(yīng)的客戶端已經(jīng)將連接關(guān)閉,那么服務(wù)端的讀操作將會返回io.EOF錯誤。

客戶端處理邏輯

客戶端處理邏輯

客戶端處理邏輯如下:

  • 客戶端在調(diào)用Dial函數(shù)與服務(wù)端建立連接后,不斷讀取用戶的輸入,通過調(diào)用連接Write方法將用戶輸入的數(shù)據(jù)發(fā)送給服務(wù)端,然后通過調(diào)用連接的Read方法讀取服務(wù)端發(fā)來的數(shù)據(jù)并顯示在客戶端,如果用戶輸入exit則調(diào)用連接的Close方法將連接關(guān)閉。

客戶端代碼如下:

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
)

func main() {
	// 客戶端連接服務(wù)器
	conn, err := net.Dial("tcp", "127.0.0.1:8081")
	if err != nil {
		fmt.Printf("connect server error, err = %v\n", err)
		return
	}
	defer conn.Close()
	fmt.Println("connect server success...")

	reader := bufio.NewReader(os.Stdin)
	data := make([]byte, 1024)
	for {
		// 1、讀取用戶輸入
		str, err := reader.ReadString('\n')
		if err != nil {
			fmt.Printf("read input error, err = %v\n", err)
			continue
		}
		str = str[:len(str)-2] // 去掉\r\n
		if str == "exit" {
			fmt.Printf("exit success...")
			break
		}

		// 2、發(fā)送數(shù)據(jù)給服務(wù)端
		n, err := conn.Write([]byte(str))
		if err != nil || n != len(str) {
			fmt.Printf("send message error, err = %v\n", err)
			continue
		}
		fmt.Printf("send %d byte message to server...\n", n)

		// 3、讀取服務(wù)端發(fā)來的數(shù)據(jù)
		n, err = conn.Read(data)
		if err != nil {
			fmt.Printf("read message error, err = %v\n", err)
			continue
		}
		fmt.Printf("server message: %v\n", string(data[:n]))
	}
}

說明一下:

  • Stdin、Stdout和Stderr是os包中的全局變量,分別表示標(biāo)準(zhǔn)輸入流、標(biāo)準(zhǔn)輸出流和標(biāo)準(zhǔn)錯誤流。
  • 客戶端在讀取用戶輸入時,通過bufio包中的Reader,以帶緩沖的方式每次從標(biāo)準(zhǔn)輸入流中讀取一行數(shù)據(jù)。
  • Windows系統(tǒng)中通常使用\r\n作為換行符,因此客戶端在每次讀取一行用戶輸入的數(shù)據(jù)后需要將末尾的兩個字符去掉。

到此這篇關(guān)于Golang TCP網(wǎng)絡(luò)編程的具體實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Golang TCP網(wǎng)絡(luò)編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Golang跨平臺GUI框架Fyne的使用教程詳解

    Golang跨平臺GUI框架Fyne的使用教程詳解

    Go 官方?jīng)]有提供標(biāo)準(zhǔn)的 GUI 框架,在 Go 實(shí)現(xiàn)的幾個 GUI 庫中,Fyne 算是最出色的,它有著簡潔的API、支持跨平臺能力,且高度可擴(kuò)展,下面我們就來看看它的具體使用吧
    2024-03-03
  • Go語言fmt.Sprintf格式化輸出的語法與實(shí)例

    Go語言fmt.Sprintf格式化輸出的語法與實(shí)例

    Go 可以使用 fmt.Sprintf 來格式化字符串,下面這篇文章主要給大家介紹了關(guān)于Go語言fmt.Sprintf格式化輸出的語法與實(shí)例,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Go語言CSP并發(fā)模型實(shí)現(xiàn)MPG

    Go語言CSP并發(fā)模型實(shí)現(xiàn)MPG

    這篇文章主要為大家介紹了Go語言CSP并發(fā)模型實(shí)現(xiàn)MPG圖文詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 關(guān)于升級go1.18的goland問題詳解

    關(guān)于升級go1.18的goland問題詳解

    作為一個go語言程序員,覺得自己有義務(wù)為go新手開一條更簡單便捷的上手之路,下面這篇文章主要給大家介紹了關(guān)于升級go1.18的goland問題的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • Golang構(gòu)建WebSocket服務(wù)器和客戶端的示例詳解

    Golang構(gòu)建WebSocket服務(wù)器和客戶端的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Go語言構(gòu)建WebSocket服務(wù)器和客戶端,以實(shí)現(xiàn)雙向通信,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下
    2023-11-11
  • golang使用swagger的過程詳解

    golang使用swagger的過程詳解

    這篇文章主要介紹了golang使用swagger的過程詳解,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • 基于Go和Gin的環(huán)境配置方法

    基于Go和Gin的環(huán)境配置方法

    今天小編就為大家分享一篇基于Go和Gin的環(huán)境配置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 從淺入深帶你掌握Golang數(shù)據(jù)結(jié)構(gòu)map

    從淺入深帶你掌握Golang數(shù)據(jù)結(jié)構(gòu)map

    在?Go?語言中,map?是一種非常常見的數(shù)據(jù)類型,它可以用于快速地檢索數(shù)據(jù)。本篇文章將介紹?Go?語言中的?map,包括?map?的定義、初始化、操作和優(yōu)化,需要的可以參考一下
    2023-04-04
  • Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Go中調(diào)用JS代碼(otto)的實(shí)現(xiàn)示例

    Otto是一個用Go語言實(shí)現(xiàn)的JavaScript解釋器,可用于執(zhí)行和操作JavaScript代碼,適合在Go項(xiàng)目中執(zhí)行簡單的JS腳本,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 使用go實(shí)現(xiàn)刪除sql里面的注釋和字符串功能(demo)

    使用go實(shí)現(xiàn)刪除sql里面的注釋和字符串功能(demo)

    這篇文章主要介紹了使用go實(shí)現(xiàn)刪除sql里面的注釋和字符串功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11

最新評論