我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Go语言网络编程:Go实现简单的内网穿透

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Go语言网络编程:Go实现简单的内网穿透

一、内网穿透

1. 内网穿透介绍

内网穿透是一种通过互联网建立远程连接到私有网络(内网)中设备的技术。通常情况下,内网设备由于位于一个受限制的网络环境中,无法直接从外部访问。内网穿透通过将内网设备的流量转发到公共网络上的服务器,然后再将该流量转发到客户端,从而实现与内网设备的通信。

2.内网穿透下访问流程

假设目前已经实现了内网穿透,以下从用户角度出发,给出了用户访问穿透后的公网网络的步骤

  1. 用户发出请求:用户通过公网地址发出一个访问请求,目标是服务端穿透后的公网地址。
  2. 服务端接收请求:服务端监听公网地址,接收到用户的请求后,将请求信息发送给客户端,如一个"New Connection"的消息。
  3. 客户端接收请求:客户端在内网中,持续监听来自服务端的信息。当接收到"New Connection"的消息后,知道有新的请求需要处理。
  4. 客户端连接隧道服务器:客户端接收到新的请求后,会创建一个新的连接到隧道服务器。隧道服务器在公网上,是客户端和服务端之间的桥梁。
  5. 客户端连接内网服务:同时,客户端也会创建一个新的连接到内网中的目标服务。这个服务是用户最初想要访问的服务。
  6. 数据转发:客户端将内网服务的数据拷贝到隧道服务器(如io.Copy(tunnelConn, clientConn)),同时将隧道服务器的数据拷贝到内网服务(io.Copy(clientConn, tunnelConn))。这样,用户的请求就通过隧道服务器,被转发到了内网服务。
  7. 服务端接收隧道数据:服务端在公网上,监听来自隧道服务器的连接。当隧道服务器有新的数据时,服务端会接收这些数据。
  8. 服务端转发数据:服务端接收到隧道服务器的数据后,会将这些数据转发给公网地址。可以通过io.Copy(appConn, tunnelConn)io.Copy(tunnelConn, appConn)实现,这两个函数将隧道服务器的数据拷贝到用户,同时将用户的数据拷贝到隧道服务器。
  9. 用户接收数据:用户最终接收到来自服务端的数据,这些数据实际上是内网服务的响应。这样,用户就成功地通过公网访问了内网服务。

以上就是用户发出访问请求到服务端、隧道、客户端的详细过程。通过这个过程,我们可以看到内网穿透是如何工作的。

二、go实现简单的内网穿透

实现内网穿透需要两个部分:客户端和服务端。客户端运行在内网中,服务端运行在公网中。客户端和服务端通过隧道进行通信,客户端将内网服务的数据发送到服务端,服务端将公网的请求发送到客户端。

要实现内网穿透,通常需要以下几个步骤:

  • 服务器端:在公网上搭建一个可被访问的服务器,用于接收外部连接和内网设备的转发流量,当然若没有公网ip,也可以使用本地的端口进行模拟
  • 客户端:在内网设备所在的计算机上运行一个客户端程序,负责将内网设备的流量转发到服务器。
  • 端口映射:将服务器上的某个端口与内网设备的指定端口进行映射,使得外部可以通过这个端口访问内网设备。
  • 数据传输:服务器接收到来自客户端的数据后,将其转发给内网设备,同时将内网设备的响应再转发回客户端。

0. 项目源码地址:https://github.com/Pistachiout/Net-Penetration

1. constant.go常量端口定义

package constantconst (// 需要内网穿透的服务端口,运行内网穿透客户端后,该端口将映射到公网,公网可以访问该端口AppPort = ":4000"// ServerPort 服务端监听端口,用于连接客户端,一般为公网端口,服务端监听该端口,接收客户端的数据,然后转发给服务端本地服务ServerPort = ":8081"// TunnelPort 隧道端口,用于客户端和服务端建立隧道,客户端和服务端通过该端口通信TunnelPort = ":8082"// AppTargetPort 穿透后的目的服务端口,在服务端端口运行客户端应用AppTargetPort = ":8083"// ServerIP 服务端公网ip地址,用于连接服务端,一般为公网IPServerIP = ""// ServerAddr 服务端监听地址,用于接收客户端的数据,然后转发给服务端本地服务ServerAddr = ServerIP + ServerPort// TunnelAddr 隧道地址,用于客户端和服务端建立隧道,客户端和服务端通过该地址通信TunnelAddr = ServerIP + TunnelPort// BufSize 缓冲区大小BufSize = 1024)

以上常量定义了在内网穿透过程中所需的各种端口和地址。

  • AppPort: 内网端口,需要内网穿透的应用端口,如web应用。当运行内网穿透客户端后,该端口将被映射到公网,使得通过公网可以访问该端口对应的服务。
  • ServerPort: 服务端监听端口。服务端监听该端口,接收客户端的数据,发给服务端本地服务。
  • TunnelPort: 隧道端口。用于客户端和服务端建立隧道通信,客户端和服务端通过该端口进行交互。
  • AppTargetPort: 穿透后的目标服务端口。在服务端端口运行客户端应用,用户可通过访问公网ip的该端口访问内网服务
  • BufSize: 缓冲区大小。定义了在数据传输过程中所使用的缓冲区大小,一般为1024字节。

这些常量提供了在内网穿透过程中所需的各种配置信息,可以根据具体的应场景和需求进行相应的调整和配置。若用户拥有公网ip,还需要添加公网ip地址

  • ServerIP: 服务端公网IP地址。用于连接服务端,一般为公网IP,用户可根据自己的公网ip进行设置。客户端需要根据这个IP来与服务端建立连接。
  • ServerAddr: 服务端监听地址。用于接收客户端的数据,然后转发给服务端本地服务。由ServerIPServerPort组合而成。
  • TunnelAddr: 隧道地址。用于客户端和服务端建立隧道通信,客户端和服务端通过该地址进行交互。由ServerIPTunnelPort组合而成。

2. 辅助函数包helper.go

package helperimport ("log""net""time")// CreateListen 监听,参数为监听地址listenAddr,返回 TCPListener,通过 net.ResolveTCPAddr 解析地址,通过 net.ListenTCP 监听端口////监听是指服务端监听某个端口,等待客户端的连接,一旦客户端连接上来,服务端就会创建一个新的goroutine处理客户端的请求。//// ResolveTCPAddr是一个解析TCP地址的函数,addr为域名或者IP地址加端口号,返回一个TCPAddr,该结构体包含了ip和port// ListenTCP函数监听TCP地址,addr则是一个TCP地址,返回值l是一个net.Listener接口,可以用来接收连接。func CreateListen(listenAddr string) (*net.TCPListener, error) {tcpAddr, err := net.ResolveTCPAddr("tcp", listenAddr)if err != nil {return nil, err}tcpListener, err := net.ListenTCP("tcp", tcpAddr)return tcpListener, err}// CreateConnect 连接,参数为服务端地址connectAddr,返回 TCPConn,通过 net.ResolveTCPAddr 解析地址,通过 net.DialTCP 连接服务端// 连接是指客户端连接服务端,连接成功后,客户端就可以向服务端发送数据了,与监听不同的是,连接是客户端发起的,而监听是服务端发起的。// DialTCP函数在网络协议tcp上连接本地地址laddr和远端地址raddrfunc CreateConnect(connectAddr string) (*net.TCPConn, error) {// 解析地址,返回TCPAddrtcpAddr, err := net.ResolveTCPAddr("tcp", connectAddr)if err != nil {return nil, err}tcpConn, err := net.DialTCP("tcp", nil, tcpAddr)return tcpConn, err}// KeepAlive 保持连接,参数为连接conn,通过循环向连接中写入数据,保持连接,每隔3秒写入一次,如果写入失败,说明连接已经断开,退出循环func KeepAlive(conn *net.TCPConn) {for {_, err := conn.Write([]byte("KeepAlive"))if err != nil {log.Printf("[KeepAlive] Error %s", err)return}time.Sleep(time.Second * 3)}}// GetDataFromConnection for循环获取Connection中的数据func GetDataFromConnection(bufSize int, conn *net.TCPConn) ([]byte, error) {b := make([]byte, 0)for {// 读取数据data := make([]byte, bufSize)n, err := conn.Read(data)if err != nil {return nil, err}b = append(b, data[:n]...)if n < bufSize {break}}return b, nil}

这段代码是项目中常用的辅助函数包,它提供了一些用于网络通信的帮助函数:

  1. CreateListen(listenAddr string) (*net.TCPListener, error):该函数用于创建一个TCP监听器。它接受一个监听地址listenAddr作为参数,并通过net.ResolveTCPAddr解析地址,然后通过net.ListenTCP监听指定的端口。函数返回一个*net.TCPListener类型的指针和一个错误。
  2. CreateConnect(connectAddr string) (*net.TCPConn, error):该函数用于创建一个TCP连接。它接受一个服务端地址connectAddr作为参数,并通过net.ResolveTCPAddr解析地址,然后通过net.DialTCP与服务端建立连接。函数返回一个*net.TCPConn类型的指针和一个错误
  3. KeepAlive(conn *net.TCPConn):该函数用于保持TCP连接的活跃状态。通过循环向连接中写入数据,保持连接,每隔3秒写入一次,如果写入失败,说明连接已经断开,退出循环
  4. GetDataFromConnection(bufSize int, conn *net.TCPConn) ([]byte, error):该函数用于从TCP连接中获取数据。它接受一个缓冲区大小bufSize和一个*net.TCPConn类型的指针作为参数。函数通过循环从连接中读取数据,并将读取的数据追加到一个字节数组中,直到读取完所有数据或达到缓冲区大小。函数返回读取到的数据字节数组和一个错误。

3. 客户端main.go

package mainimport ("Net-Penetration/constant""Net-Penetration/helper""io""log")// 内网穿透客户端,用于将本地服务映射到公网,使得公网可以访问本地服务,实现内网穿透,func main() {// 连接服务端conn, err := helper.CreateConnect(constant.ServerAddr)if err != nil {panic(err)}log.Printf("连接成功,连接地址为:%s\n", conn.RemoteAddr().String())// 保持连接,读取数据for {// 从连接中读取数据data, err := helper.GetDataFromConnection(constant.BufSize, conn)if err != nil {log.Printf("读取数据失败,错误信息为:%s\n", err.Error())continue}log.Printf("接收到数据:%s\n", string(data))// 判断是否为新连接,如果是新连接,则连接隧道服务器,否则转发消息if string(data) == "New Connection" {// 连接隧道服务器go messgaeForward()}}}// 连接隧道服务器进行消息转发func messgaeForward() {// 连接隧道服务器tunnelConn, err := helper.CreateConnect(constant.TunnelAddr)if err != nil {panic(err)}// 连接客户端服务clientConn, err := helper.CreateConnect(constant.AppPort)if err != nil {panic(err)}//消息转发//io.Copy()函数实现了数据的拷贝,可以将数据从一个接口拷贝到另一个接口,这里将客户端的数据拷贝到隧道服务器,将隧道服务器的数据拷贝到客户端//io.Copy()函数会一直阻塞,直到两个接口中的数据全部拷贝完成go io.Copy(clientConn, tunnelConn)go io.Copy(tunnelConn, clientConn)}
  1. main()函数:该函数是程序的入口点。它首先通过helper.CreateConnect函数连接到服务端,并打印连接地址。然后进入一个无限循环,从连接中读取数据。如果读取到的数据是"New Connection",则调用messgaeForward()函数连接隧道服务器进行消息转发。
  2. messgaeForward()函数:该函数用于连接隧道服务器并进行消息转发。它首先通过helper.CreateConnect函数分别连接到隧道服务器和客户端服务。然后使用io.Copy函数将客户端的数据拷贝到隧道服务器,将隧道服务器的数据拷贝到客户端。这样可以实现消息的双向转发。
    内网穿透的实现主要涉及到两个部分:客户端(Client)和服务端(Server)。下面我们将从代码角度出发,详细解释这两部分如何实现内网穿透。

客户端的主要任务是连接到服务端,并将内网服务的数据发送到服务端。这是通过以下关键步骤实现的:

  1. 连接到服务端:客户端首先需要连接到服务端。这是通过helper.CreateConnect(constant.ServerAddr)函数实现的,该函数创建一个到服务端的TCP连接。
  2. 读取服务端数据:客户端连接到服务端后,需要读取服务端发送的数据。这是通过helper.ReadMessage(serverConn)函数实现的,该函数从服务端连接中读取数据。
  3. 处理服务端数据:客户端读取到服务端数据后,需要根据数据内容进行相应的处理。如果读取到的数据是"New Connection",则需要连接到隧道服务器进行消息转发。
  4. 消息转发:消息转发是通过messgaeForward()函数实现的。该函数首先连接到隧道服务器和客户端服务,然后将客户端服务的数据拷贝到隧道服务器,同时将隧道服务器的数据拷贝到客户端服务。

4.服务端main.go

package mainimport ("Net-Penetration/constant""Net-Penetration/helper""io""log""net""sync")// serverConn 服务端连接var serverConn *net.TCPConn// appConn 目的服务端连接var appConn *net.TCPConn// wg 用于等待所有协程结束var wg sync.WaitGroup// 内网穿透服务端func main() {//监听服务端go serverListen()//监听目的服务端go appListen()//启动隧道服务go tunnelListen()//等待所有协程结束wg.Add(1)wg.Wait()}func serverListen() {//监听服务端,用于接收客户端连接tcpListener, err := helper.CreateListen(constant.ServerAddr)if err != nil {panic(err)}log.Printf("服务端监听地址为:%s\n", tcpListener.Addr().String())//接收客户端连接for {serverConn, err = tcpListener.AcceptTCP()if err != nil {log.Printf("接收连接失败,错误信息为:%s\n", err.Error())return}//保持连接go helper.KeepAlive(serverConn)}}// 监听隧道服务,用于接收隧道客户端连接,隧道客户端连接用于转发目的服务端和客户端之间的消息,实现内网穿透func tunnelListen() {tcpListener, err := helper.CreateListen(constant.TunnelAddr)if err != nil {panic(err)}log.Printf("隧道监听地址为:%s\n", tcpListener.Addr().String())for {tunnelConn, err := tcpListener.AcceptTCP()if err != nil {log.Printf("接收连接失败,错误信息为:%s\n", err.Error())return}// 数据转发go io.Copy(appConn, tunnelConn)go io.Copy(tunnelConn, appConn)}}// 监听目的服务端,用于接收目的服务端连接,目的服务端可以是本地转发的端口,也可以是远程服务器的端口func appListen() {//监听目的服务端tcpListener, err := helper.CreateListen(constant.AppTargetPort)if err != nil {panic(err)}log.Printf("应用目的服务端监端口地址为:%s\n", tcpListener.Addr().String())for {appConn, err = tcpListener.AcceptTCP()if err != nil {log.Printf("接收连接失败,错误信息为:%s\n", err.Error())return}_, err := serverConn.Write([]byte("New Connection"))if err != nil {log.Printf("发送消息失败,错误信息为:%s\n", err.Error())}}}
  1. main()函数:该函数是程序的入口点。它启动了三个协程,分别用于监听服务端、目的服务端和隧道服务端。然后使用sync.WaitGroup等待所有协程结束。
  2. serverListen()函数:该函数用于监听客户端连接。它首先通过helper.CreateListen函数创建一个TCP监听器,并打印监听地址。然后进入一个无限循环,接收客户端连接。每当有新的客户端连接时,将其保持活跃,并启动一个新的协程进行处理。
  3. appListen()函数:该函数用于监听目的服务端连接。它首先通过helper.CreateListen函数创建一个TCP监听器,并打印监听地址。然后进入一个无限循环,接收目的服务端连接。每当有新的目的服务端连接时,向客户端发送"New Connection"的消息。
  4. tunnelListen()函数:该函数用于监听隧道客户端连接。它首先通过helper.CreateListen函数创建一个TCP监听器,并打印监听地址。然后进入一个无限循环,接收隧道客户端连接。每当有新的隧道客户端连接时,启动两个新的协程,分别将数据从隧道客户端拷贝到目的服务端,以及将数据从目的服务端拷贝到隧道客户端。

服务端的主要任务是监听客户端连接、目的服务端连接和隧道客户端连接,并进行数据转发。这是通过以下关键步骤实现的:

  1. 监听客户端连接:服务端首先需要监听客户端连接。这是通过helper.CreateListen(constant.ServerListenAddr)函数实现的,该函数创建一个监听客户端连接的TCP监听器。
  2. 处理客户端连接:服务端接收到客户端连接后,需要保持连接。这是通过helper.KeepAlive(serverConn)函数实现的,该函数保持与客户端的连接。
  3. 监听目的服务端连接:服务端需要监听目的服务端连接。这是通过helper.CreateListen(constant.AppTargetPort)函数实现的,该函数创建一个监听目的服务端连接的TCP监听器。
  4. 处理目的服务端连接:服务端接收到目的服务端连接后,需要向客户端发送"New Connection"的消息。这是通过serverConn.Write([]byte("New Connection"))实现的。
  5. 监听隧道客户端连接:服务端需要监听隧道客户端连接。这是通过helper.CreateListen(constant.TunnelListenAddr)函数实现的,该函数创建一个监听隧道客户端连接的TCP监听器。
  6. 数据转发:服务端接收到隧道客户端连接后,需要进行数据转发。这是通过io.Copy(appConn, tunnelConn)io.Copy(tunnelConn, appConn)实现的,这两个函数将隧道客户端的数据拷贝到目的服务端,同时将目的服务端的数据拷贝到隧道客户端。

5.应用端测试main.go

package mainimport ("Net-Penetration/constant""encoding/json""log""net/http")// 本地应用,用于测试内网穿透func main() {http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {q := request.URL.Query()b, err := json.Marshal(q)if err != nil {log.Println(err)}writer.Write(b)})log.Printf("本地服务已启动:%s\n", constant.AppPort)http.ListenAndServe(constant.AppPort, nil)}

6.1 本地测试步骤:

首先运行服务端main.go
2. 运行客户端main.go
3. 运行应用端main.go
4. 此时可分别打开AppPort和AppTargetPort均可发现应用服务

在这里插入图片描述

6.2 公网ip测试步骤:以Linux云服务器为例

  1. 首先修改constant.go中的ServerIP为自己的公网ip
  2. 将服务端main.go打包,上传到Linux云服务器,并添加权限。windows下将go程序打包为linux可执行程序需要配置go编译环境,具体参考windows下将go程序打包为linux可执行程序教程
  3. 在服务器运行上传的main
  4. 在客户端运行客户端main.go
  5. 运行应用端main.go
  6. 此时可打开公网ip:AppTargetPort可发现内网的应用服务

来源地址:https://blog.csdn.net/qq_45808700/article/details/131417192

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Go语言网络编程:Go实现简单的内网穿透

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

破解Go语言网络编程的秘密

深入理解Go语言网络编程的奥秘,需要具体代码示例网络编程是当今计算机领域中非常重要的一部分,而Go语言作为一门现代化的编程语言,提供了丰富的网络编程功能和简洁的语法,使得开发人员可以更加方便地实现各种网络应用。在深入理解Go语言网络编程
破解Go语言网络编程的秘密
2024-01-30

Go语言在网络编程中的实践与运用

Go语言作为一种现代化的编程语言,在网络编程领域具有许多独特的优势。它的简洁、高效以及并发特性使得它成为许多工程师首选的语言之一。在本文中,我们将探讨Go语言在网络编程领域的实践与应用。首先,让我们回顾一下Go语言的一些特性。Go语言是由
Go语言在网络编程中的实践与运用
2024-02-25

高效掌握Go语言网络编程的实践指南

快速入门Go语言网络编程的实用指南引言:随着互联网的不断发展和普及,网络编程已成为越来越重要的一项技能。Go语言作为一种现代化的编程语言,具有高效、简洁、易学的特点,自然也就成为了很多开发者进行网络编程的首选语言。本文将针对初学者,提供一
高效掌握Go语言网络编程的实践指南
2024-01-30

Go语言在网络编程中的应用探究

go 语言非常适合网络编程,本文概述了其应用,包括:建立 http 服务器:使用 net/http 包创建简单的 http 服务器。处理 http 请求:使用 http.handler 接口根据请求路径处理请求。创建 websocket 服
Go语言在网络编程中的应用探究
2024-04-04

Go语言网络编程的关键知识和实践指南

掌握Go语言网络编程的关键要点与实践经验,需要具体代码示例一、Go语言网络编程的关键要点网络编程简介网络编程是指使用计算机网络进行通信的编程技术。在Go语言中,我们可以借助标准库中的net包进行网络编程,包括创建和管理TCP、UDP连
Go语言网络编程的关键知识和实践指南
2024-01-30

Go语言在网络编程中的优点和实际应用

Go语言在网络编程中的优势与应用随着互联网的快速发展,网络编程变得愈发重要。在网络编程中,选择一种高效且易用的编程语言至关重要。Go语言(或称Golang)作为一种由Google开发的静态编译型语言,因其并发模型、高效性能以及简洁的语法而
Go语言在网络编程中的优点和实际应用
2024-02-25

Go语言网络编程的实现策略与案例研究:高效解密

解密Go语言网络编程的高效实现策略与案例分析引言随着互联网的迅猛发展和多样化需求的不断出现,网络编程变得越来越重要。而Go语言作为一门现代化的编程语言,以其出色的并发能力和简洁的语法,越来越受到开发者的青睐。本文将探讨Go语言网络编程的
Go语言网络编程的实现策略与案例研究:高效解密
2024-01-30

如何用Go语言开发一个简单的社交网络应用

如何用Go语言开发一个简单的社交网络应用引言社交网络已经成为人们日常生活中不可或缺的一部分。随着技术的发展,开发一个属于自己的社交网络应用已经变得越来越简单。本文将以Go语言为开发工具,介绍如何快速开发一个简单的社交网络应用。第一步:设计数
如何用Go语言开发一个简单的社交网络应用
2023-11-20

深入探讨Go语言网络编程中的非NIO技术

从现在开始,我们要努力学习啦!今天我给大家带来《深入探讨Go语言网络编程中的非NIO技术》,感兴趣的朋友请继续看下去吧!下文中的内容我们主要会涉及到等等知识点,如果在阅读本文过程中有遇到不清楚的地方,欢迎留言呀!我们一起讨论,一起学习!Go
深入探讨Go语言网络编程中的非NIO技术
2024-04-04

学习Go语言网络编程的有效方法和技巧

从零开始学习Go语言网络编程的方法与技巧,需要具体代码示例近年来,Go语言在网络编程领域中展现出了强大的能力,成为了许多开发者的首选语言。Go语言以其高效的并发模型、简洁的语法和出色的性能,尤其适用于构建高性能的网络应用程序。如果你想从零
学习Go语言网络编程的有效方法和技巧
2024-01-30

探索Go语言在网络编程领域的优势与应用

随着互联网的快速发展,网络编程成为了软件开发中的重要领域之一。在众多编程语言中,Go语言因其并发模型、高性能和丰富的标准库而备受开发者青睐,尤其在网络编程领域展现出了许多优势。本文将探索Go语言在网络编程领域的优势以及实际应用。1. 并发
探索Go语言在网络编程领域的优势与应用
2024-02-22

Go语言在大数据处理和网络编程中的应用

Go语言是一种编译型、并发性强的程序设计语言,由Google开发而成,自问世以来在大数据处理和网络编程中展现出了强大的能力。本文将着重探讨Go语言在大数据处理和网络编程方面的应用,并提供一些具体的代码示例。大数据处理是当前信息时代一个重要
Go语言在大数据处理和网络编程中的应用
2024-03-02

Go语言中如何处理网络编程中的并发问题?

Go语言中如何处理网络编程中的并发问题?在网络编程中,处理并发问题是非常重要的。Go语言作为一门支持并发的编程语言,提供了丰富的并发编程工具和简化并发编程的语法,为我们解决网络编程中的并发问题提供了良好的支持。首先,我们可以使用gorout
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录