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

yizhihongxing

这里是关于实现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日

相关文章

  • Linux系列教程(二十一)——Linux的bash基本功能

    Linux系列教程(二十一)——Linux的bash基本功能的完整攻略 Bash是Linux系统中最常用的shell,它提供了很多强大的功能,括命令行编辑、命令历史、命令自动补全、别名、脚本编等。本文将为您提供Bash基功能的完整攻略,包括命令行编辑、命令历史、命令自动补全别名和脚本编写等。 命令行编辑 Bash提供了命令行编辑功能,可以让用户在命令行中进行…

    other 2023年5月6日
    00
  • input file获得文件根目录简单实现

    首先,我们需要了解什么是input file。input file是HTML5新增的一种表单类型,用于让用户选择并上传本地文件。接着,我们来看一下如何使用input file实现文件根目录的简单获取。 HTML代码 首先,我们需要在HTML代码中添加一个input标签并设置type为file,这样就创建了一个文件选择框,代码如下: <input typ…

    other 2023年6月27日
    00
  • Lua中创建全局变量的小技巧(禁止未预期的全局变量)

    Lua中创建全局变量的小技巧(禁止未预期的全局变量) 在Lua中,全局变量的创建和使用是非常灵活的,但有时候我们希望限制全局变量的使用,以避免意外创建未预期的全局变量。下面是一些小技巧,可以帮助我们实现这个目标。 使用全局变量表 Lua中有一个特殊的表 _G,它是一个全局变量表,包含了所有的全局变量。我们可以通过操作这个表来限制全局变量的创建。 — 禁止未…

    other 2023年7月29日
    00
  • C++教程之array数组使用示例详解

    C++教程之array数组使用示例详解 本篇文章主要介绍C++中数组的使用方法,包括声明、初始化、遍历、使用等详细攻略。 数组的声明和初始化 定义数组时需要指定数组类型、数组名称和数组长度。C++中数组的长度必须是一个常量表达式。 // 定义一个长度为5的int类型数组 int array1[5]; // 定义一个长度为4的double类型数组,并初始化 d…

    other 2023年6月25日
    00
  • 魔兽世界8.0鸟德天赋特质推荐及输出手法介绍

    魔兽世界8.0鸟德天赋特质推荐及输出手法介绍攻略 介绍 鸟德,即“风暴之鸟德鲁伊”,是魔兽世界中的一个近战输出职业。在8.0版本中鸟德的天赋及特质有了非常大的调整,本攻略将介绍鸟德在8.0版本中的天赋特质,并提供一些输出手法,帮助玩家更好的使用鸟德角色。 基础技能 在阅读本攻略之前,需要了解鸟德的基础技能。常用的基础技能如下: 近战技能:爪击、旋风斩 远程技…

    other 2023年6月27日
    00
  • GTA5网购车做任务老是丢解决方法介绍

    GTA5网购车做任务老是丢解决方法介绍 在玩GTA5时,可能会遇到这样一个问题:买了网购车却在做任务时经常会丢失,这是为什么呢?如何解决?下面我们就一起来看看。 为什么会丢失网购车 首先,我们需要了解一下网购车的特点。网购车是可以在网上商店购买的虚拟车辆。它们不同于你在游戏中得到的那些车辆,它们不能被你的人物保管起来,而是必须使用保险公司的服务来代替。 当你…

    other 2023年6月27日
    00
  • 深入sizeof的使用详解

    标题:深入sizeof的使用详解 简介 sizeof是一个C/C++语言中的运算符,用来计算数据类型或变量的大小,通常会被用来在程序中动态地分配内存。在使用sizeof时,有一些细节需要注意,这篇文章将详细介绍如何深入使用sizeof。 sizeof的使用 1. sizeof基础用法 sizeof运算符可以用来计算数据类型或变量所占的内存大小,其基本语法如下…

    other 2023年6月26日
    00
  • Swift4.0 Array数组详解

    Swift4.0 Array数组详解 在Swift中,Array是一种常用的数据类型,它可以用来存储一组有序的、相同类型的数据。在本篇文章中,我们将对Swift中的Array做一个详细介绍,包括Array的创建、访问、遍历、增删改查等操作。 创建Array 在Swift中,可以使用以下几种方式来创建一个Array: 使用字面量 字面量是指将数组中的元素使用[…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部