前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言点对点通信

Go语言点对点通信

原创
作者头像
IT工作者
发布2022-04-02 10:19:34
5070
发布2022-04-02 10:19:34
举报
文章被收录于专栏:程序技术知识程序技术知识

一.概述

点对点通信就是客户端A发送消息给服务端,再由服务端把消息传递给客户端B.相同道理客户端B想给客户端A发送消息也需要把消息传递给服务端,再由服务端把消息传递给A

正常情况下客户端A和客户端B可以通过用户名、IP等唯一身份标识区分每个用户.在本功能练习中要求客户端先注册用户名,然后告诉服务端给谁发消息.如果用户名存在不允许注册

在本功能练习中用户信息存储到临时容器map中,没有进行持久化操作.

二.代码实现

项目结构如下

--项目名

--src

--client

client.go

--serve

server.go

main.go

在server.go中编写代码

代码语言:javascript
复制
package main

import (
    "net"
    "fmt"
    "strings"
)

type User struct {
    Username      string
    OtherUsername string
    Msg           string
    ServerMsg     string
}

var (
    userMap = make(map[string]net.Conn)
    user    = new(User)
)

func main() {
    addr, _ := net.ResolveTCPAddr("tcp4", ":9999")
    lis, _ := net.ListenTCP("tcp4", addr)

    for {
        conn, _ := lis.Accept()
        go func() {
            for {
                b := make([]byte, 512)
                //读取数据
                count, _ := conn.Read(b)

                arrStr := strings.Split(string(b[:count]), "-")
                user.Username = arrStr[0]
                user.OtherUsername = arrStr[1]
                user.Msg = arrStr[2]
                user.ServerMsg = arrStr[3]
                userMap[user.Username] = conn
                if v, ok := userMap[user.OtherUsername]; ok && v != nil {
                    user.ServerMsg = ""
                    n, e := v.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))
                    if n == 0 || e != nil {
                        conn.Close()
                        delete(userMap, user.OtherUsername)
                        break
                    }
                } else {
                    user.ServerMsg = "对方不在线"
                    n, e := conn.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))
                }
            }
        }()
    }
}

在client.go中编写代码

代码语言:javascript
复制
package main

import (
    "net"
    "fmt"
    "sync"
    "os"
    "strings"
)

type User struct {
    Username      string
    OtherUsername string
    Msg           string
    ServerMsg     string
}

var (
    user = new(User)
    wg   sync.WaitGroup
)

func main() {
    wg.Add(1)
    fmt.Println("请登录,输入用户名:")
    fmt.Scanln(&user.Username)
    fmt.Println("请输入要给谁发送消息")
    fmt.Scanln(&user.OtherUsername)
    addr, _ := net.ResolveTCPAddr("tcp4", ":9999")
    conn, _ := net.DialTCP("tcp4", nil, addr)
    go func() {
        fmt.Print("请输入:(只提示一次,以后直接输入即可)")
        for {
            fmt.Scanln(&user.Msg)
            if user.Msg == "exit" {
                conn.Close()
                wg.Done()
                os.Exit(0)
            }
            conn.Write([]byte(fmt.Sprintf("%s-%s-%s-%s", user.Username, user.OtherUsername, user.Msg, user.ServerMsg)))
        }
    }()
    go func() {
        for {
            rb := make([]byte, 512)
            c, _ := conn.Read(rb)
            user2 := new(User)
            arrStr := strings.Split(string(rb[:c]), "-")
            user2.Username = arrStr[0]
            user2.OtherUsername = arrStr[1]
            user2.Msg = arrStr[2]
            user2.ServerMsg = arrStr[3]
            if user2.ServerMsg != "" {
                fmt.Println("\t\t\t服务器消息:", user2.ServerMsg)
            } else {
                fmt.Println("\t\t\t", user2.Username, ":", user2.Msg)
            }
        }
    }()
    wg.Wait()
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档