golang 实现tcp server端和client端,并计算RTT时间操作

这里是关于实现golang TCP服务器端和客户端,并计算RTT时间操作的完整攻略。下面我们一步步来实现。

初始设置

首先,为了实现TCP服务器端和客户端,可以使用Go语言标准库中的net包,这个包提供了各种用于网络通信的功能,我们需要引入这个包,如下:

import (
    "net"
)

接下来,我们需要定义一些常量、变量等,在本例中我们需要定义服务器和客户端的IP地址和端口号,并且定义一个用于接收客户端消息的缓冲区:

const (
    ip   = "127.0.0.1"
    port = "8888"
)

var receiveBuf = make([]byte, 1024)

其中,ip是我们的服务器和客户端都在本地运行,所以使用127.0.0.1进行本地回环,port则是服务器和客户端通信使用的端口号。

实现TCP服务器端

接下来我们来实现TCP服务器端,下面的代码展示了如何创建一个TCP服务器,侦听指定的IP地址和端口号,并监听客户端发来的连接请求:

ln, err := net.Listen("tcp", ip+":"+port)
if err != nil {
    panic(err)
}
defer ln.Close()

for {
    conn, err := ln.Accept()
    if err != nil {
        log.Println(err)
        continue
    }

    go handleClient(conn)
}

在代码中,我们先调用Listen函数创建侦听对象ln,用于监听指定IP地址和端口号,如果有客户端连接,会调用Accept函数进行处理。其中,handleClient函数是用于处理客户端连接的具体逻辑,我们稍后会讲到此函数的实现方法。

接下来,我们来编写handleClient函数,用于具体实现客户端连接的处理逻辑:

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

    // 接收数据
    n, err := conn.Read(receiveBuf)
    if err != nil {
        log.Println(err)
        return
    }

    // 获取客户端发送的消息并显示
    message := string(receiveBuf[:n])
    log.Println(message)

    // 计算返回消息的RTT时间
    rt := time.Now().Sub(start)
    log.Printf("RTT: %v", rt)

    // 向客户端发送消息
    _, err = conn.Write([]byte("Message received"))
    if err != nil {
        log.Println(err)
        return
    }
}

以上代码实现的逻辑如下:首先,我们定义一个defer语句,确保在函数执行完毕后立即关闭连接。然后,我们通过连接对象的Read方法来读取客户端发送的消息,并将其存储在缓冲区中。接下来,根据需要,我们可以在log中显示来自客户端的消息。

除此之外,在这个函数内我们还计算了返回消息的RTT时间,并使用计算出来的时间值在log中显示。最后,我们使用连接对象的Write方法将一个简单的确认消息发送回客户端,以告知客户端消息已接收。

到这里,我们的TCP服务器实现就完成了。

实现TCP客户端

接下来我们来实现TCP客户端。下面的代码展示了如何创建一个TCP连接,并向服务器发送消息:

conn, err := net.Dial("tcp", ip+":"+port)
if err != nil {
    panic(err)
}
defer conn.Close()

// 向服务器发送消息
_, err = conn.Write([]byte("Hello World"))
if err != nil {
    log.Println(err)
    return
}

// 接收服务器返回的消息
n, err := conn.Read(receiveBuf)
if err != nil {
    log.Println(err)
    return
}

message := string(receiveBuf[:n])
log.Println(message)

在代码中,我们首先通过Dial函数创建一个TCP连接对象conn,并向指定的IP地址和端口号发起连接请求。如果连接成功,我们就可以使用Write方法发送消息,使用Read方法接收消息。最后,我们显示接收到的消息。

到这里,我们的TCP客户端实现就完成了。

示例

下面,我们来演示一下实际的运行功能:

TCP服务器

package main

import (
    "log"
    "net"
    "time"
)

const (
    ip   = "127.0.0.1"
    port = "8888"
)

var receiveBuf = make([]byte, 1024)

func main() {
    // 启动服务器
    ln, err := net.Listen("tcp", ip+":"+port)
    if err != nil {
        panic(err)
    }
    defer ln.Close()

    for {
        conn, err := ln.Accept()
        if err != nil {
            log.Println(err)
            continue
        }

        go handleClient(conn)
    }
}

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

    // 接收数据
    n, err := conn.Read(receiveBuf)
    if err != nil {
        log.Println(err)
        return
    }

    // 获取客户端发送的消息并显示
    message := string(receiveBuf[:n])
    log.Println(message)

    // 计算返回消息的RTT时间
    rt := time.Now().Sub(start)
    log.Printf("RTT: %v", rt)

    // 向客户端发送消息
    _, err = conn.Write([]byte("Message received"))
    if err != nil {
        log.Println(err)
        return
    }
}

TCP客户端

package main

import (
    "log"
    "net"
)

const (
    ip   = "127.0.0.1"
    port = "8888"
)

var receiveBuf = make([]byte, 1024)

func main() {
    // 连接服务器
    conn, err := net.Dial("tcp", ip+":"+port)
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 向服务器发送消息
    _, err = conn.Write([]byte("Hello World"))
    if err != nil {
        log.Println(err)
        return
    }

    // 接收服务器返回的消息
    n, err := conn.Read(receiveBuf)
    if err != nil {
        log.Println(err)
        return
    }

    message := string(receiveBuf[:n])
    log.Println(message)
}

以上代码在运行时,当客户端发送消息时,服务器会显示该消息,并计算处理时间,并返回一个简单的确认消息。客户端则显示接收到的确认消息。在此基础上,可以根据需要进行扩展和修改,以实现更复杂的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang 实现tcp server端和client端,并计算RTT时间操作 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • java如何用递归方法求阶乘

    可以使用递归方法来求阶乘,递归可以将问题划分为多个小问题,然后用相同的方法解决它们,最后将它们的答案组合在一起。下面是Java代码示例: public class Factorial { public static void main(String[] args) { int num = 5; int result = factorial(num); Sys…

    other 2023年6月27日
    00
  • Linux下用于对比文件的diff命令使用教程

    Linux下用于对比文件的diff命令使用教程 diff命令是Linux下用于对比文件差异的工具。它可以比较两个文件的内容,并显示它们之间的不同之处。下面是diff命令的使用教程,包含两个示例说明。 基本语法 diff [选项] <文件1> <文件2> 选项说明 -q:仅显示文件是否不同,不显示具体差异内容。 -r:递归比较目录及其子…

    other 2023年8月18日
    00
  • 详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)

    详解 axios 中封装使用、拦截特定请求、判断所有请求加载完毕 封装 Axios Axios 是一款基于 Promise 的 HTTP 请求库,让我们在浏览器端和 Node.js 中发起 HTTP 请求变得非常容易。但是,为了更好的使用和维护,我们需要对 Axios 进行封装。 我们可以将 Axios 封装成一个单独的模块,该模块会创建一个新的 Axios…

    other 2023年6月25日
    00
  • 网络防火墙与防范溢出策略(解决方案)

    网络防火墙是保障互联网安全的重要手段,防范溢出攻击则是网络安全的关键措施之一。下面,我们将分两个方面详细讲解如何实施网络防火墙与防范溢出攻击。 网络防火墙 什么是网络防火墙? 网络防火墙(Firewall)是在计算机网络中实施信息访问控制的一种重要设备,也是流量控制和安全管理的重要手段。它可以在网络内外之间起到屏障、过滤和监视的作用,保障网络的安全和稳定运行…

    other 2023年6月26日
    00
  • python 如何对logging日志封装

    下面是Python对logging日志的封装攻略: 1. 理解 logging 模块的基本概念 logging 模块是Python内置的日志管理库,用于输出程序运行时的日志信息。为了更好的封装 logging 模块,我们需要先理解它的基本概念。 logging 模块中包含以下几个重要的类: Logger:logger是一个提供了应用程序可直接使用的接口。它负…

    other 2023年6月25日
    00
  • Win11 22H2怎么快速恢复完整右键菜单? Win11右键选项的设置方法

    下面是Win11 22H2快速恢复完整右键菜单的攻略: 问题背景 在使用Win11系统时,右键菜单是我们经常使用的功能之一,但有时我们会发现右键菜单不完整或者某些选项丢失,这个问题常常让我们感到非常困扰,那么该怎么办呢? 解决方法 方法一:通过注册表编辑器恢复右键菜单 按下Win键+R,打开运行命令框,在命令框中输入regedit,打开注册表编辑器。 在注册…

    other 2023年6月27日
    00
  • 详细解析列表设计的基本思路

    以下是详细解析列表设计的基本思路的完整攻略。 确定列表类型 在开始设计列表之前,需要首先确定列表的类型。通常情况下,一个列表可以是以下几种类型之一。 有序列表:使用数字、字母或罗马数字来表示列表的顺序。 无序列表:使用符号、点或其他形式来表示列表的条目。 定义列表:包含一系列术语和其定义。 在确定列表类型后,可以使用合适的 markdown 标记来开始设计列…

    other 2023年6月27日
    00
  • macbrew安装使用卸载

    MacBrew安装使用卸载 介绍 MacBrew是苹果系统上的一种包管理工具,可以快速、简单地安装、升级和管理各种软件包,包括命令行工具、开发库、Web服务等。它使用简单,管理方便,广泛用于Mac开发者和运维人员之间,是一个非常实用的软件管理工具。 安装 1.安装Homebrew 在终端中输入以下命令: /usr/bin/ruby -e “$(curl -f…

    其他 2023年3月29日
    00
合作推广
合作推广
分享本页
返回顶部