Go 语言高级网络编程

news2025/2/25 11:30:40

深入探讨 Go 语言的网络编程

img

简介

Go(Golang)中的网络编程具有易用性、强大性和乐趣。本指南深入探讨了网络编程的复杂性,涵盖了协议、TCP/UDP 套接字、并发等方面的内容,并附有详细的注释。

关键概念

1. 网络协议

  • TCP(传输控制协议):确保可靠的数据传输。
  • UDP(用户数据报协议):更快,但不保证数据传递。

2. 套接字

  • TCP 套接字:用于面向连接的通信。
  • UDP 套接字:用于无连接通信。

3. 并发

  • Goroutines(协程):允许在代码中实现并行处理。
  • Channels(通道):用于协程之间的通信。

示例

示例 1:TCP 服务器和客户端

TCP 服务器和客户端示例演示了TCP通信的基础。

服务器

package main

import (
 "net"
 "fmt"
)

func main() {
 // Listen on TCP port 8080 on all available unicast and
 // any unicast IP addresses.
 listen, err := net.Listen("tcp", ":8080")
 if err != nil {
  fmt.Println(err)
  return
 }
 defer listen.Close()

 // Infinite loop to handle incoming connections
 for {
  conn, err := listen.Accept()
  if err != nil {
   fmt.Println(err)
   continue
  }
  // Launch a new goroutine to handle the connection
  go handleConnection(conn)
 }
}

func handleConnection(conn net.Conn) {
 defer conn.Close()
 buffer := make([]byte, 1024)
 // Read the incoming connection into the buffer.
 _, err := conn.Read(buffer)
 if err != nil {
  fmt.Println(err)
  return
 }
 // Send a response back to the client.
 conn.Write([]byte("Received: " + string(buffer)))
}

客户端

package main

import (
 "net"
 "fmt"
)

func main() {
 // Connect to the server at localhost on port 8080.
 conn, err := net.Dial("tcp", "localhost:8080")
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // Send a message to the server.
 conn.Write([]byte("Hello, server!"))
 buffer := make([]byte, 1024)
 // Read the response from the server.
 conn.Read(buffer)
 fmt.Println(string(buffer))
}

服务器在端口8080上等待连接,读取传入的消息并发送响应。客户端连接到服务器,发送消息并打印服务器的响应。

示例 2:UDP 服务器和客户端

与TCP不同,UDP是无连接的。以下是UDP服务器和客户端的实现。

服务器

package main

import (
 "net"
 "fmt"
)

func main() {
 // Listen for incoming UDP packets on port 8080.
 conn, err := net.ListenPacket("udp", ":8080")
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 buffer := make([]byte, 1024)
 // Read the incoming packet data into the buffer.
 n, addr, err := conn.ReadFrom(buffer)
 if err != nil {
  fmt.Println(err)
  return
 }
 fmt.Println("Received: ", string(buffer[:n]))
 // Write a response to the client's address.
 conn.WriteTo([]byte("Message received!"), addr)
}

客户端

package main

import (
 "net"
 "fmt"
)

func main() {
 // Resolve the server's address.
 addr, err := net.ResolveUDPAddr("udp", "localhost:8080")
 if err != nil {
  fmt.Println(err)
  return
 }

 // Dial a connection to the resolved address.
 conn, err := net.DialUDP("udp", nil, addr)
 if err != nil {
  fmt.Println(err)
  return
 }
 defer conn.Close()

 // Write a message to the server.
 conn.Write([]byte("Hello, server!"))
 buffer := make([]byte, 1024)
 // Read the response from the server.
 conn.Read(buffer)
 fmt.Println(string(buffer))
}

服务器从任何客户端读取消息并发送响应。客户端发送消息并等待响应。

示例 3:并发 TCP 服务器

并发允许同时处理多个客户端。

package main

import (
 "net"
 "fmt"
)

func main() {
 // Listen on TCP port 8080.
 listener, err := net.Listen("tcp", ":8080")
 if err != nil {
  fmt.Println(err)
  return
 }
 defer listener.Close()

 for {
  // Accept a connection.
  conn, err := listener.Accept()
  if err != nil {
   fmt.Println(err)
   continue
  }
  // Handle the connection in a new goroutine.
  go handleConnection(conn)
 }
}

func handleConnection(conn net.Conn) {
 defer conn.Close()
 buffer := make([]byte, 1024)
 // Read the incoming connection.
 conn.Read(buffer)
 fmt.Println("Received:", string(buffer))
 // Respond to the client.
 conn.Write([]byte("Message received!"))
}

通过为每个连接使用新的 goroutine,多个客户端可以同时连接。

示例 4:带有 Gorilla Mux 的 HTTP 服务器

Gorilla Mux 库简化了 HTTP 请求路由。

package main

import (
 "fmt"
 "github.com/gorilla/mux"
 "net/http"
)

func main() {
 // Create a new router.
 r := mux.NewRouter()
 // Register a handler function for the root path.
 r.HandleFunc("/", homeHandler)
 http.ListenAndServe(":8080", r)
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
 // Respond with a welcome message.
 fmt.Fprint(w, "Welcome to Home!")
}

这段代码设置了一个 HTTP 服务器,并为根路径定义了一个处理函数。

示例 5:HTTPS 服务器

实现 HTTPS 服务器可以确保安全通信。

package main

import (
 "net/http"
 "log"
)

func main() {
 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  // Respond with a message.
  w.Write([]byte("Hello, this is an HTTPS server!"))
 })
 // Use the cert.pem and key.pem files to secure the server.
 log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))
}

服务器使用 TLS(传输层安全性)来加密通信。

示例 6:自定义 TCP 协议

可以使用自定义的 TCP 协议进行专门的通信。

package main

import (
 "net"
 "strings"
)

func main() {
 // Listen on TCP port 8080.
 listener, err := net.Listen("tcp", ":8080")
 if err != nil {
  panic(err)
 }
 defer listener.Close()

 for {
  // Accept a connection.
  conn, err := listener.Accept()
  if err != nil {
   panic(err)
  }
  // Handle the connection in a new goroutine.
  go handleConnection(conn)
 }
}

func handleConnection(conn net.Conn) {
 defer conn.Close()
 buffer := make([]byte, 1024)
 // Read the incoming connection.
 conn.Read(buffer)
 // Process custom protocol command.
 cmd := strings.TrimSpace(string(buffer))
 if cmd == "TIME" {
  conn.Write([]byte("The current time is: " + time.Now().String()))
 } else {
  conn.Write([]byte("Unknown command"))
 }
}

这段代码实现了一个简单的自定义协议,当客户端发送命令“TIME”时,它会回复当前时间。

示例 7:使用 Gorilla WebSocket 进行 WebSockets

WebSockets 提供了通过单一连接的实时全双工通信。

package main

import (
 "github.com/gorilla/websocket"
 "net/http"
)

var upgrader = websocket.Upgrader{
 ReadBufferSize:  1024,
 WriteBufferSize: 1024,
}

func handler(w http.ResponseWriter, r *http.Request) {
 conn, err := upgrader.Upgrade(w, r, nil)
 if err != nil {
  http.Error(w, "Could not open websocket connection", http.StatusBadRequest)
  return
 }
 defer conn.Close()

 for {
  messageType, p, err := conn.ReadMessage()
  if err != nil {
   return
  }
  // Echo the message back to the client.
  conn.WriteMessage(messageType, p)
 }
}

func main() {
 http.HandleFunc("/", handler)
 http.ListenAndServe(":8080", nil)
}

WebSocket 服务器会将消息回传给客户端。

示例 8:连接超时

可以使用 context 包来管理连接超时。

package main

import (
 "context"
 "fmt"
 "net"
 "time"
)

func main() {
 // Create a context with a timeout of 2 seconds
 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
 defer cancel()

 // Dialer using the context
 dialer := net.Dialer{}
 conn, err := dialer.DialContext(ctx, "tcp", "localhost:8080")
 if err != nil {
  panic(err)
 }

 buffer := make([]byte, 1024)
 _, err = conn.Read(buffer)
 if err == nil {
  fmt.Println("Received:", string(buffer))
 } else {
  fmt.Println("Connection error:", err)
 }
}

这段代码为从连接读取数据设置了两秒的截止时间。

示例 9:使用 golang.org/x/time/rate 进行速率限制

速率限制控制请求的速率。

package main

import (
 "golang.org/x/time/rate"
 "net/http"
 "time"
)

// Define a rate limiter allowing two requests per second with a burst capacity of five.
var limiter = rate.NewLimiter(2, 5)

func handler(w http.ResponseWriter, r *http.Request) {
 // Check if request is allowed by the rate limiter.
 if !limiter.Allow() {
  http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
  return
 }
 w.Write([]byte("Welcome!"))
}

func main() {
 http.HandleFunc("/", handler)
 http.ListenAndServe(":8080", nil)
}

此示例使用速率限制器,将请求速率限制为每秒两个请求,突发容量为五个。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1067930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码小王子:国庆后上班的『表情包』神器

引言 哎哟,国庆七天乐就像手里握着的沙子,一不小心就从指间滑落了。🤔 小伙伴们,是不是感觉还没玩儿够,就要面对冷酷的现实——上班了!😟 但是,咱们要以最饱满的热情,最…

力扣 53. 最大子数组和(C语言+分治递归、动态规划)

1. 题目 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。 2. 输入输出样例 示例 1: 输入:nums [-2,1,-3,4,-1,2,1…

java进阶-第8章-IO流

一、File类 概念:代表物理盘符中的一个文件或者文件夹。 常见方法: 方法名描述createNewFile()创建一个新文件。mkdir()创建一个新目录。delete()删除文件或空目录。exists()判断File对象所对象所代表的对象是否存在。getAbsolutePath()获取文件的绝对…

最新 SpringCloud微服务技术栈实战教程 微服务保护 分布式事务 课后练习等

SpringCloud微服务技术栈实战教程,涵盖springcloud微服务架构Nacos配置中心分布式服务等 SpringCloud及SpringCloudAlibaba是目前最流行的微服务技术栈。但大家学习起来的感受就是组件很多,不知道该如何应用。这套《微服务实战课》从一个单体项目入手&am…

【Python】下载和安装

【Python】下载和安装 下载 进入 Python官网,下载最新版本,如下图所示: 如果需要下载其他版本,请下滑该页面,找到如下位置,选择需要的版本进行下载(以3.8.10为例): 点击…

运行软件找不到mfc140u.dll怎么解决,mfc140u.dll是什么文件

"找不到 mfc140u.dll"是一条错误信息,表示您的计算机上缺少一个名为 mfc140u.dll 的动态链接库(DLL)文件。这个文件通常与 Microsoft Visual C Redistributable 相关。Mfc140u.dll 是 Microsoft 基础类库(MFC&#xff0…

当 FineReport 遇见 CnosDB

随着大数据和物联网应用的快速发展,时序数据库成为了一种关键的数据存储和分析工具。而 FineReport 作为一款流行的商业智能工具,与时序数据库 CnosDB 的集成可以为企业提供更强大的数据分析和可视化功能。本博客将介绍如何将 FineReport 与 CnosDB 集成…

CSS点击切换或隐藏盒子的卷起、展开效果

<template><div class"main"><el-button click"onCllick">切换</el-button><transition name"slideDown"><div class"info" v-if"isShow">1111</div></transition></di…

云数据库保护需要注意哪些事项?

云数据库保护是在云计算环境中对数据库进行保护和安全管理的重要措施。随着云计算的普及和应用&#xff0c;云数据库的保护也变得尤为重要。以下是安策分享的关于云数据库保护需要注意的一些事项。 云数据库的访问控制是保护数据库的首要任务。只有授权的用户或应用程序才能访问…

win11系统下,将WSL2从系统盘(C盘)迁移到迁移到数据盘(D盘)

WSL2迁移磁盘 网上的一些方法 今天希望把WSL迁移到D盘&#xff0c;原因就是C盘剩余空间太少了&#xff0c;系统有一点卡顿&#xff0c;然后百度了一下迁移的方法&#xff0c;发现真的是八仙过海&#xff0c;各显神通啊&#xff0c;改注册表、exclude为.tar然后重新导入等等&a…

MVCC和BufferPool缓存机制

文章目录 1. MVCC多版本并发控制机制2. BufferPool缓存机制 1. MVCC多版本并发控制机制 Mysql可以在可重复读隔离级别下可以保证事务较高的隔离性&#xff0c;这个隔离性是由MVCC机制来保证的&#xff0c;对一行数据的读和写两个操作默认是不会通过加锁互斥来保证隔离性&#…

alsa pcm接口之pcm设备的状态STATE

应用和库之间的协作: ALSA pcm api设计使用状态来确定应用程序和库之间的通信阶段,实际的状态可以被决定通过使用snd_pcm_state调用,下面列举出来状态: SND_PCM_STATE_OPEN: 表示pcm设备被打开的状态,使用了snd_pcm_open()之后进入该状态,并且让snd_pcm_hw_params()调用失败后,…

Safran助力dSPACE实现基于GNSS驾驶功能的HIL仿真

概述 世界知名的模拟与验证方案厂商dSPACE借助虹科Safran GNSS模拟器实现了一套基于GNSS的驾驶功能HIL仿真系统&#xff0c;该系统可以用于自动驾驶、车联网、智能座舱等各类汽车行业应用&#xff0c;并具备极大的灵活性与多功能&#xff0c;适用于各类复杂场景测试。 方案介绍…

vscode更改为中文版本

方式一 在扩展里安装chinese插件 方式二 1.Ctrl&#xff0b; Shift &#xff0b;P&#xff08;commandshiftP&#xff09; 2.输入Configure display Language 3.选择zh-cn 这时候vscode会提示需要重启&#xff0c;点击restart重启vscode&#xff0c;重启后vscode就会显示中…

找不到msvcp140_1.dll怎么办,快速解决msvcp140_1.dll问题的方法分享

在日常使用计算机的过程中&#xff0c;经常会遇到一些程序无法正常运行的问题&#xff0c;其中最常见的就是“msvcp140_1.dll丢失”。这是一个典型的DLL文件丢失问题&#xff0c;但背后的原因却往往并不简单。通过深入研究这个问题&#xff0c;我对其有了更深入的理解。 首先&a…

【沐风老师】3DMAX彩灯串灯生成器使用方法详解

3DMAX彩灯串灯生成器使用教程 3DMAX彩灯串灯生成器&#xff0c;可以让你毫不费力地从场景中选定的线图形创建令人惊叹的串灯模型。可以在线条中单独生成灯泡和电线&#xff0c;有九种不同类型的灯泡可供用户选择&#xff0c;以实现各种照明效果和装饰。该工具具有一系列可自定义…

漏洞复现-易思无人值守智能物流文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

Rust Http 性能测试框架/工具

在Rust中&#xff0c;有几个常用的性能测试框架和工具可用于对HTTP性能进行测试。以下是其中一些&#xff1a; 1、Criterion&#xff1a;Criterion是一个通用的性能测试框架&#xff0c;可以用于测试各种类型的代码性能&#xff0c;包括HTTP性能。你可以使用Criterion来编写和运…

pnpm、npm、yarn 包管理工具『优劣对比』及『环境迁移』

前言 博主在开发前端网站的时候&#xff0c;发现随着开发的项目的逐渐增多&#xff0c;安装的依赖包越来越臃肿&#xff0c;依赖包的安装速度也是非常越来越慢&#xff0c;多项目开发管理也是比较麻烦。之前我就了解过 pnpm&#xff0c;但是当时担心更换包管理环境可能会出现的…

在微信小程序中如何引入iconfont

目录 前言iconfont 介绍iconfont 组建图标库并下载1. 通过 iconfont 可组建自己的图标库2. 项目设置&#xff1a;生成base64格式的字体3. 下载至本地4. 解压备用 将 iconfont 添加到小程序中1. 将css该名称wxss2. 将文件复制到font目录3. 在app.wxss文件中引入iconfont文件 在小…