Swoole与Go系列教程之TCP服务的应用

简介: TCP(传输控制协议)的出现是为了解决计算机网络中的数据可靠传输和连接管理的问题。在早期的计算机网络中,特别是在分组交换和互联网的发展初期,网络是不可靠的,存在丢包、错误和延迟等问题。

大家好,我是码农先森。

写在前面

TCP(传输控制协议)的出现是为了解决计算机网络中的数据可靠传输和连接管理的问题。在早期的计算机网络中,特别是在分组交换和互联网的发展初期,网络是不可靠的,存在丢包、错误和延迟等问题。为了保证数据能够可靠地传输,需要一种协议来提供可靠的传输机制。而早期的协议如UDP(用户数据报协议)是无连接的、不可靠的,无法满足应用程序对连接管理的需求。TCP协议提供一种标准化、可靠的数据传输服务,促进了互联网的发展和应用的普及。

TCP 协议原理

TCP(传输控制协议)是一种可靠的、面向连接的传输层协议。它提供了一种端到端的可靠数据传输机制,确保数据在不可靠的网络中按序送达,并且无差错、无重复和无丢失。

请在此添加图片描述

  • 源端口(Source Port):指发送端(客户端)使用的端口号。在 TCP 连接中,源端口标识了发送数据的应用程序或进程。
  • 目的端口(Destination port):指接收端(服务器)用于接收数据的端口号。它位于 TCP 报文段的头部中的目的端口字段。
  • 序列号(Sequence Number):序列号是用于对发送的数据进行分段和重组的编号。它标识了 TCP 报文段中的数据字节的顺序。序列号字段位于 TCP 报文段的头部,并且是一个32位的字段。
  • 应答号(Acknowledgment Number):是指发送方期望接收到的下一个序列号。它是TCP报文头部中的一个字段,用于确认已经成功接收到的数据。
  • 首部长度(Header Lenght):它表示TCP首部的长度,指示了TCP报文头部所占用的字节数。
  • 保留(Reserved):指TCP报文段头部中的一些预留字段,它们保留为未来使用而暂时未定义其具体含义。
  • 窗口大小(Window Size):是一个用于流量控制的参数,它表示接收方所能接收的未确认数据的最大字节数。
  • 校验和(Check Sum):是一种用于检测数据完整性的机制,它用于验证TCP报文段在传输过程中是否发生了位错误或损坏。
  • 紧急指针(Urgent Pointer):是一种用于标识数据流中的紧急数据的机制。它用于告知接收方数据流中存在需要优先处理的紧急数据。
  • CWR(Congestion Window Reduce):表示拥塞窗口减少标志,用于指示发送方收到了一个ECN报文,并相应地减小了拥塞窗口的大小。
  • ECE(ECN Echo):表示显式拥塞通告回显,用于指示接收方支持并报告网络拥塞情况。
  • URG(Urgent):表示TCP报文段中存在紧急数据,并且需要在正常数据之前被优先处理。
  • PSH(Push):表示接收方在接收到该TCP报文后应该立即将数据推送给上层应用,而不是等待缓冲区满或者计时器触发。
  • RST(Reset):表示复位标志位。RST标志位在TCP报文段中用于终止连接,它用于关闭一个非正常或不可恢复的连接。
  • SYN(Synchronize):表示同步标志位。用于发起连接的建立过程。
  • FIN(Finish):表示结束标志位,用于连接的关闭过程。

请在此添加图片描述

TCP三次握手是建立TCP连接时使用的一种协议,其步骤如下:

第一次握手(SYN):
客户端向服务器发送一个带有SYN(同步)标志位的数据包,用于请求建立连接。该数据包中会携带客户端的初始序列号。

第二次握手(SYN + ACK):
服务器收到客户端的连接请求后,会向客户端发送带有SYN和ACK(确认)标志位的数据包作为响应。该数据包中会携带服务器的初始序列号,并确认客户端的序列号。

第三次握手(ACK):
客户端收到服务器的响应后,会向服务器发送一个带有ACK标志位的数据包进行确认。这个确认信号代表客户端已经准备就绪,连接已建立。

双方完成以上三个步骤后,TCP连接建立成功,可以开始进行数据传输。

请在此添加图片描述

TCP四次挥手是用于关闭TCP连接的协议,其步骤如下:

第一次挥手(FIN):
当客户端决定关闭连接时,会发送一个带有FIN(结束)标志位的数据包给服务器,表示不再发送数据,但仍然可以接收数据。

第二次挥手(ACK):
服务器收到客户端的关闭请求后,会发送一个带有ACK标志位的数据包作为确认响应。该数据包表示服务器已经接收到了客户端的关闭请求。

第三次挥手(FIN):
当服务器也准备关闭连接时,会向客户端发送一个带有FIN标志位的数据包,表示服务器不再发送数据。此时,服务器也进入了关闭等待状态。

第四次挥手(ACK):
客户端收到服务器的关闭请求后,会发送一个带有ACK标志位的数据包作为确认响应。该数据包表示客户端已经接收到了服务器的关闭请求,连接将被完全关闭。

在四次挥手完成后,双方都进入了关闭状态,释放连接资源,并确保最后的数据段都能够被可靠地传递。这样可避免因为网络延迟或丢包而导致的数据传输错误或资源浪费。

在 Swoole 中的应用

  1. 使用new Swoole\Server('0.0.0.0', 9501)创建了一个TCP服务器对象,监听0.0.0.0地址和9501端口
  2. 使用$server->on('connect', function ($server, $fd) { ... });监听TCP连接事件。
  3. 当有新的TCP连接建立时,会执行回调函数内的代码。回调函数中,将打印出新连接的文件描述符($fd)。
  4. 使用$server->on('receive', function ($server, $fd, $fromId, $data) { ... });监听TCP数据接收事件。
  5. 使用$server->on('close', function ($server, $fd) { ... });监听TCP连接关闭事件。
  6. 当有TCP连接关闭时,会执行回调函数内的代码。回调函数中,将打印出关闭连接的文件描述符($fd)。
  7. 使用$server->start();启动TCP服务器,使其开始监听并处理连接请求。
<?php

// 创建 TCP 服务器对象,监听 0.0.0.0:9501 端口
$server = new Swoole\Server('0.0.0.0', 9501);

// 监听 TCP 连接事件
$server->on('connect', function ($server, $fd) {
    echo "New TCP connection established: {$fd}\n";
});

// 监听 TCP 数据接收事件
$server->on('receive', function ($server, $fd, $fromId, $data) {
    echo "Received data from {$fd}: {$data}\n";

    // 向客户端发送回复消息
    $server->send($fd, 'Hello from Swoole server!');
});

// 监听 TCP 连接关闭事件
$server->on('close', function ($server, $fd) {
    echo "TCP connection closed: {$fd}\n";
});

// 启动 TCP 服务器
$server->start();

在 Go 语言中的应用

  1. 使用net.Listen("tcp", "0.0.0.0:9501")函数在0.0.0.0:9501地址上创建了一个TCP监听器。
  2. 使用listener.Accept()函数接受客户端的连接请求。
  3. 对于每个连接请求,使用handleConnection(conn)函数处理连接。
  4. 为了并发处理多个连接,使用go关键字将处理连接的任务放入一个新的goroutine中执行。
  5. 初始化一个缓冲区buffer,使用conn.Read()函数从连接中读取数据
  6. 然后,使用conn.Write()函数向客户端发送回复消息"Hello from Go server!"
package main

import (
    "fmt"
    "net"
)

// nc 0.0.0.0:9501
func main() {
    // 监听 0.0.0.0:9501 地址
    listener, err := net.Listen("tcp", "0.0.0.0:9501")
    if err != nil {
        fmt.Println("Failed to start TCP server:", err)
        return
    }
    defer listener.Close()

    fmt.Println("TCP server started on 0.0.0.0:9501")

    for {
        // 接受客户端连接请求
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println("Error accepting connection:", err)
            continue
        }

        // 处理客户端连接
        go handleConnection(conn)
    }
}

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

    fmt.Println("New TCP connection established:", conn.RemoteAddr())

    // 处理接收和发送数据
    buffer := make([]byte, 1024)
    for {
        n, err := conn.Read(buffer)
        if err != nil {
            fmt.Println("Error reading data:", err)
            break
        }

        data := buffer[:n]
        fmt.Printf("Received data from %s: %s\n", conn.RemoteAddr(), string(data))

        // 回复消息给客户端
        conn.Write([]byte("Hello from Go server!"))

        // 处理完数据后结束连接
        break
    }

    fmt.Println("TCP connection closed:", conn.RemoteAddr())
}

总结

  1. TCP 协议提供了可靠的传输方式,让数据的传输有了保障。
  2. Swoole 对连接的处理,是在进程中进行的。
  3. Go 语言针对每个连接,都分配了一个协程进行处理,提高了服务的处理能力。

欢迎关注、分享、点赞、收藏、在看,我是微信公众号「码农先森」作者。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
95 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
4天前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
51 20
|
3月前
|
缓存 监控 前端开发
在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统
本文深入探讨了在 Go 语言中实现 WebSocket 实时通信的应用,包括 WebSocket 的简介、Go 语言的优势、基本实现步骤、应用案例、注意事项及性能优化策略,旨在帮助开发者构建高效稳定的实时通信系统。
198 1
|
3月前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
3月前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
3月前
|
Go UED
Go Web服务中如何优雅平滑重启?
在生产环境中,服务升级时如何确保不中断当前请求并应用新代码是一个挑战。本文介绍了如何使用 Go 语言的 `endless` 包实现服务的优雅重启,确保在不停止服务的情况下完成无缝升级。通过示例代码和测试步骤,详细展示了 `endless` 包的工作原理和实际应用。
78 3
|
3月前
|
JSON Go UED
Go Web服务中如何优雅关机?
在构建 Web 服务时,优雅关机是一个关键的技术点,它确保服务关闭时所有正在处理的请求都能顺利完成。本文通过一个简单的 Go 语言示例,展示了如何使用 Gin 框架实现优雅关机。通过捕获系统信号和使用 `http.Server` 的 `Shutdown` 方法,我们可以在服务关闭前等待所有请求处理完毕,从而提升用户体验,避免数据丢失或不一致。
47 1
|
4月前
|
Cloud Native Go API
Go语言在微服务架构中的创新应用与实践
本文深入探讨了Go语言在构建高效、可扩展的微服务架构中的应用。Go语言以其轻量级协程(goroutine)和强大的并发处理能力,成为微服务开发的首选语言之一。通过实际案例分析,本文展示了如何利用Go语言的特性优化微服务的设计与实现,提高系统的响应速度和稳定性。文章还讨论了Go语言在微服务生态中的角色,以及面临的挑战和未来发展趋势。
|
4月前
|
运维 Go 开发者
Go语言在微服务架构中的应用与优势
本文深入探讨了Go语言在构建微服务架构中的独特优势和实际应用。通过分析Go语言的核心特性,如简洁的语法、高效的并发处理能力以及强大的标准库支持,我们揭示了为何Go成为开发高性能微服务的首选语言。文章还详细介绍了Go语言在微服务架构中的几个关键应用场景,包括服务间通信、容器化部署和自动化运维等,旨在为读者提供实用的技术指导和启发。
|
3月前
|
SQL 监控 算法
为Go应用无侵入地添加任意代码
这篇文章旨在提供技术深度和实践指南,帮助开发者理解并应用这项创新技术来提高Golang应用的监控与服务治理能力。在接下来的部分,我们将通过一些实际案例,进一步展示如何在不同场景中应用这项技术,提供更多实践启示。

热门文章

最新文章