Go实现网络通信

Go 语言提供了强大的网络编程能力,包括 TCP、UDP、HTTP、WebSocket 等协议的支持。下面是 Go 语言中常用的网络操作:

TCP 通信

使用 net 包进行 TCP 通信,可以创建 TCP 客户端和服务器。
客户端使用 net.Dial 方法连接到指定的 TCP 地址,并使用返回的连接对象进行通信。
服务器使用 net.Listen 方法监听指定的 TCP 地址,接受客户端连接,并使用返回的连接对象进行通信。

TCP 客户端

package mainimport ("fmt""net"
)func main() {// 连接到 TCP 服务器conn, err := net.Dial("tcp", "localhost:8080")if err != nil {fmt.Println("无法连接到服务器:", err)return}defer conn.Close()// 发送数据message := "Hello, TCP server!"_, err = conn.Write([]byte(message))if err != nil {fmt.Println("发送数据失败:", err)return}// 接收服务器响应buffer := make([]byte, 1024)n, err := conn.Read(buffer)if err != nil {fmt.Println("接收响应失败:", err)return}fmt.Println("服务器响应:", string(buffer[:n]))
}

TCP 服务器

package mainimport ("fmt""net"
)func main() {// 监听 TCP 连接listener, err := net.Listen("tcp", "localhost:8080")if err != nil {fmt.Println("无法监听端口:", err)return}defer listener.Close()fmt.Println("等待客户端连接...")for {// 接受客户端连接conn, err := listener.Accept()if err != nil {fmt.Println("接受连接失败:", err)continue}// 处理客户端请求go handleClient(conn)}
}func handleClient(conn net.Conn) {defer conn.Close()// 接收客户端数据buffer := make([]byte, 1024)n, err := conn.Read(buffer)if err != nil {fmt.Println("读取数据失败:", err)return}fmt.Println("接收到客户端数据:", string(buffer[:n]))// 发送响应给客户端response := "Hello, TCP client!"_, err = conn.Write([]byte(response))if err != nil {fmt.Println("发送响应失败:", err)return}
}

UDP 通信

使用 net 包进行 UDP 通信,可以创建 UDP 客户端和服务器。
客户端使用 net.DialUDP 方法连接到指定的 UDP 地址,并使用返回的连接对象进行通信。
服务器使用 net.ListenUDP 方法监听指定的 UDP 地址,接收客户端发送的数据,并使用返回的连接对象进行通信。

UDP 客户端

package mainimport ("fmt""net"
)func main() {// 连接到 UDP 服务器conn, err := net.Dial("udp", "localhost:8080")if err != nil {fmt.Println("无法连接到服务器:", err)return}defer conn.Close()// 发送数据message := "Hello, UDP server!"_, err = conn.Write([]byte(message))if err != nil {fmt.Println("发送数据失败:", err)return}
}

UDP 服务器

package mainimport ("fmt""net"
)func main() {// 监听 UDP 连接addr, err := net.ResolveUDPAddr("udp", "localhost:8080")if err != nil {fmt.Println("无法解析地址:", err)return}conn, err := net.ListenUDP("udp", addr)if err != nil {fmt.Println("无法监听端口:", err)return}defer conn.Close()fmt.Println("等待客户端连接...")// 接收客户端数据buffer := make([]byte, 1024)n, addr, err := conn.ReadFromUDP(buffer)if err != nil {fmt.Println("读取数据失败:", err)return}fmt.Println("接收到客户端数据:", string(buffer[:n]))// 发送响应给客户端response := "Hello, UDP client!"_, err = conn.WriteToUDP([]byte(response), addr)if err != nil {fmt.Println("发送响应失败:", err)return}
}

HTTP通信

HTTP 客户端

使用 net/http 包进行 HTTP 客户端编程,可以发送 HTTP 请求并接收响应。
使用 http.Get、http.Post 等方法发送不同类型的 HTTP 请求。
可以通过设置请求头、请求方法、请求体等来定制请求,并使用响应对象获取服务器的响应数据。

  1. 发起 HTTP GET 请求:
package mainimport ("fmt""io/ioutil""net/http"
)func main() {// 发送 GET 请求response, err := http.Get("http://localhost:8080")if err != nil {fmt.Println("发送请求失败:", err)return}defer response.Body.Close()// 读取响应内容body, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println("读取响应失败:", err)
return}fmt.Println("服务器响应:", string(body))
}
  1. 发起 HTTP POST 请求:
package mainimport ("bytes""fmt""net/http""io/ioutil"
)func main() {url := "https://jsonplaceholder.typicode.com/posts" // 要发送 POST 请求的网址payload := []byte(`{"title": "foo", "body": "bar", "userId": 1}`)resp, err := http.Post(url, "application/json", bytes.NewBuffer(payload))if err != nil {fmt.Println("HTTP POST 请求失败:", err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("读取响应体失败:", err)return}fmt.Println("POST 响应:", string(body))
}
  1. 发起 HTTP PUT 请求:
package mainimport ("bytes""fmt""net/http""io/ioutil"
)func main() {url := "https://jsonplaceholder.typicode.com/posts/1" // 要更新的资源网址payload := []byte(`{"id": 1, "title": "foo", "body": "bar", "userId": 1}`)req, err := http.NewRequest("PUT", url, bytes.NewBuffer(payload))req.Header.Set("Content-Type", "application/json")client := &http.Client{}resp, err := client.Do(req)if err != nil {fmt.Println("HTTP PUT 请求失败:", err)return}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("读取响应体失败:", err)return}fmt.Println("PUT 响应:", string(body))
}

HTTP 服务器

使用 net/http 包进行 HTTP 服务器编程,可以创建一个 HTTP 服务器来处理客户端的请求。
使用 http.HandleFunc 方法来注册处理不同路由的处理函数,或者使用自定义的 http.Handler 对象处理请求。
可以通过设置路由和处理逻辑来实现 RESTful API、静态文件服务等功能。

package mainimport ("fmt""net/http"
)func main() {// 注册处理函数http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {fmt.Fprint(w, "Hello, HTTP client!")})// 启动 HTTP 服务器err := http.ListenAndServe(":8080", nil)if err != nil {fmt.Println("启动服务器失败:", err)return}
}

WebSocket 通信

使用 net/http 包进行 WebSocket 通信,可以创建一个 WebSocket 服务器和客户端。
服务器可以使用 http.HandleFunc 方法来注册 WebSocket 的处理函数,处理客户端的连接和消息。
客户端可以使用 gorilla/websocket 等第三方库来建立 WebSocket 连接,并进行消息的发送和接收。

WebSocket 服务器

package mainimport ("fmt""log""net/http""github.com/gorilla/websocket"
)func main() {// 注册 WebSocket 处理函数http.HandleFunc("/", handleWebSocket)// 启动 WebSocket 服务器err := http.ListenAndServe(":8080", nil)if err != nil {log.Fatal("启动服务器失败:", err)}
}func handleWebSocket(w http.ResponseWriter, r *http.Request) {// 升级 HTTP 连接为 WebSocket 连接upgrader := websocket.Upgrader{}conn, err := upgrader.Upgrade(w, r, nil)if err != nil {log.Println("升级连接失败:", err)return}defer conn.Close()fmt.Println("客户端已连接")// 处理 WebSocket 消息for {// 读取消息_, message, err := conn.ReadMessage()if err != nil {log.Println("读取消息失败:", err)break}fmt.Println("接收到消息:", string(message))// 发送消息err = conn.WriteMessage(websocket.TextMessage, []byte("Hello, WebSocket client!"))if err != nil {log.Println("发送消息失败:", err)break}}fmt.Println("客户端已断开连接")
}

WebSocket 客户端(使用 JavaScript)

const socket = new WebSocket("ws://localhost:8080");// 连接建立时触发
socket.onopen = function() {console.log("连接已建立");// 发送消息socket.send("Hello, WebSocket server!");
};// 接收消息时触发
socket.onmessage = function(event) {console.log("接收到消息:", event.data);
};// 连接关闭时触发
socket.onclose = function(event) {console.log("连接已关闭");
};

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

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

相关文章

JVM与Java体系结构

目录 一、Java虚拟机整体架构祥图 二、Java代码执行过程详图 三、汇编语言、机器语言、高级语言关系 四、JVM的架构模型 五、JVM的生命周期 (一)虚拟机的启动 (二)虚拟机的执行 (三)虚拟机的退出 …

使用示例和应用程序全面了解高效数据管理的Golang MySQL数据库

Golang,也被称为Go,已经成为构建强大高性能应用程序的首选语言。在处理MySQL数据库时,Golang提供了一系列强大的库,简化了数据库交互并提高了效率。在本文中,我们将深入探讨一些最流行的Golang MySQL数据库库&#xff…

数据库管理-第113期 Oracle Exadata 04-硬件选择(20231020)

数据库管理-第113期 Oracle Exadata 04-硬件选择(2023010290) 本周没写文章,主要是因为到上海参加了Oracle CAB/PAB会议,这个放在后面再讲,本期讲一讲Exadata,尤其是存储节点的硬件选择及其对应的一些通用…

mac安装并使用wireshark

mac安装并使用wireshark 1 介绍 我们在日常开发过程中,遇到了棘手的问题时,免不了查看具体网络请求情况,这个时候就需要用到抓包工具。比较著名的抓包工具就属:wireshark、fildder。我这里主要介绍wireshark。 2 安装 以mac安装为…

C#,数值计算——分类与推理Svmpolykernel的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class Svmpolykernel : Svmgenkernel { public int n { get; set; } public double a { get; set; } public double b { get; set; } public double d { get; set; …

多线程---synchronized特性+原理

文章目录 synchronized特性synchronized原理锁升级/锁膨胀锁消除锁粗化 synchronized特性 互斥 当某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象的synchronized就会阻塞等待。 进入synchronized修饰的代码块相当于加锁 退出synchronize…

LuatOS-SOC接口文档(air780E)--max30102 - 心率模块

max30102.init(i2c_id,int)# 初始化MAX30102传感器 参数 传入值类型 解释 int 传感器所在的i2c总线id,默认为0 int int引脚 返回值 返回值类型 解释 bool 成功返回true, 否则返回nil或者false 例子 if max30102.init(0,pin.PC05) thenlog.info("max30102&q…

IDEA MyBatisX插件介绍

一、前言 前几年写代码的时候,要一键生成DAO、XML、Entity基础代码会采用第三方工具,比如mybatis-generator-gui等,现在IDEA或Eclipse都有对应的插件,像IDEA中MyBatisX就是一个比较好用的插件。 二、MyBatisX安装配置使用 MyBa…

GO学习之 通道(nil Channel妙用)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…

Vue虚拟DOM理解 | 深入且易懂

文章目录 前言虚拟DOM理解什么是虚拟DOM虚拟DOM转为真实DOM组件的本质模板工作原理 前言 本篇文章部分内容来源于霍春阳 《Vue.js设计与实现》这本书的理解, 感兴趣的小伙伴可以自行购买阅读。可以非常明确的感受到作者对 Vue 的深刻理解以及用心, 富含非常全面的 Vue 的知识点…

面试经典150题——Day26

文章目录 一、题目二、题解 一、题目 392. Is Subsequence Given two strings s and t, return true if s is a subsequence of t, or false otherwise. A subsequence of a string is a new string that is formed from the original string by deleting some (can be none…

Mac电脑Android Studio和VS Code配置Flutter开发环境(图文超详细)

一、安装Android Studio 官网地址: https://developer.android.google.cn/ 历史版本下载地址: https://developer.android.com/studio/archive?hlzh-cn 二、安装Xcode 到App Store下载安装最新版本,如果MacOS更新不到13.0以上就无法安装…

Go-Python-Java-C-LeetCode高分解法-第十二周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏,每日一题,和博主一起进步 LeetCode专栏 我搜集到了50道精选题,适合速成概览大部分常用算法 突…

消息中间件——RabbitMQ(一)Windows/Linux环境搭建(完整版)

前言 最近在学习消息中间件——RabbitMQ,打算把这个学习过程记录下来。此章主要介绍环境搭建。此次主要是单机搭建(条件有限),包括在Windows、Linux环境下的搭建,以及RabbitMQ的监控平台搭建。 环境准备 在搭建Rabb…

机器人的触发条件有什么区别,如何巧妙的使用

简介​ 维格机器人触发条件,分为3个,分别是: 有新表单提交时、有记录满足条件时、有新的记录创建时 。 看似3个,其实是能够满足我们非常多的使用场景。 本篇将先介绍3个条件的触发条件,然后再列举一些复杂的触发条件如何用现有的触发条件来满足 注意: 维格机器人所有的…

【Python第三方包】串口通信(pySerial包)

文章目录 前言一、串口的基本使用1.1 配置串口基本信息1.2 读取串口数据1.3 写串口1.4 关闭串口二、示例代码2.1 示例1: 从串口读取数据2.2 示例2: 向串口写入数据总结前言 串口通信是许多嵌入式和物联网应用中的关键组成部分。Python 提供了许多第三方库来简化串口通信的实现…

Linux(Centos7)防火墙端口操作记录

1、nginx -t #Nginx配置文件检查 上述截图代表检查没问题 上述截图检查配置文件配置错误,并提示错误文件位置 2、systemctl restart nginx #重启Nginx 重启Nginx失败 3、systemctl status nginx.service #查看Nginx服务状态 80端口被占导致服务启动失败 4、n…

MYSQL(索引篇)

一、什么是索引 索引是一种数据结构,它用来帮助MYSQL更高效的获取数据 采用索引可以提高数据检索的效率,降低IO成本 通过索引对数据排序,降低数据排序成本,降低CPU消耗 常见的有:B树索引、B树索引、哈希索引。其中Inno…

leetcode 238. 除自身以外数组的乘积

leetcode 238. 除自身以外数组的乘积 题目说明&#xff0c;不能使用除法&#xff0c;没有思路。 答案一&#xff1a;超时&#xff0c;因为left、right和result一开始没有设置数组大小&#xff0c;存取浪费时间。 class Solution { public:vector<int> productExceptSel…

【Python】 Python之markdown模块

Python之markdown模块 为了编辑和维护方便使用的是MD来编辑(数据库和文档都是MD)&#xff0c;但是实际展示中生成的API中&#xff0c;需要HTML标签来展示&#xff0c;故此这里需要一个能转换的工具来帮忙。 1. 其他库&#xff1a; markdown markdown2 snudown 2. 安装&…