[golang]实现Tcp协议之简单C/S模型

先来看下面这张图!

这里写图片描述
这个图清晰的展示了tcp协议下的C/S模型运行机制,首先我们先来执行图片右边的TCP服务器。由于go语言天生支持并发,我们就直接展示并发的服务器模型。

//这是一个用来处理连接进来的用户的函数
func handleconn(conn net.Conn)  {
    defer conn.Close()
    buf:=make([]byte,1024)
    //给客户端发送连接成功的信号
    conn.Write([]byte("welcome to my server\n"))
    for  {
    //持续读取客户端数据,保存在buf缓冲区中,并处理
        n,err:=conn.Read(buf)
        if n==0 {
            fmt.Println("outtoleave",conn.RemoteAddr().String())
            break
        }
        if err!=nil&&err!=io.EOF {
            fmt.Println("read err",err)
            return
        }
        //这里是处理数据的一个示范,把客户端发来的数据全部转化为大写
        conn.Write([]byte(strings.ToUpper(string(buf[:n]))))
    }
}

func main() {
//图片的第一步,net.listen开启监听,获得listener套接字
    listener,err:=net.Listen("tcp","127.0.0.1:6666")
    if err!=nil {
        fmt.Println("listen err",err)
        return
    }
    defer listener.Close()
    for  {
    //开启图片中的第二步,阻塞等待用户连接
        conn,err:=listener.Accept()
        if err!=nil {
            fmt.Println("accept err",err)
            return
        }
        //每一个连接进来的用户都为其分配一个专属的go进程
        go handleconn(conn)
    }
}

下面再来实现图片左边的TCP客户端模型,由图可知,相较于服务器模型,客户端模型还要少一步。下面不多比比,直接进代码分析:

package main

import (
    "net"
    "fmt"
    "os"
)

func main()  {
//主动发起连接请求
    conn,err:=net.Dial("tcp","127.0.0.1:8000")
    if err!=nil {
        fmt.Println("dial err",err)
        return
    }
    defer conn.Close()
    //启动go进程,持续接收用户键盘输入
    go func() {
    //创建缓冲区
        buf:=make([]byte,1024)
        for  {
        //持续接收放进缓冲区buf中
            n,err:=os.Stdin.Read(buf)
            //错误处理
            if err!=nil {
                fmt.Println("stdin err",err)
                return
            }
            //接收多少,写多少给服务器
            _,err=conn.Write(buf[:n])
            if err!=nil {
                fmt.Println("write err",err)
                return
            }
        }
    }()
    //主进程接收服务器信息
    buf:=make([]byte,4096)
    for  {
        n,err:=conn.Read(buf)
        //没有信息时,说明断开了连接,则主动结束进程
        if n==0 {
            fmt.Println("与服务器连接断开")
            break
        }
        if err!=nil {
            fmt.Println("read err",err)
            return
        }
        //打印接收到的信息
        fmt.Println(string(buf[:n]))
    }
}

以上两段代码就实现了简单的并发C/S模型,有问题的小伙伴可以在下面给我留言哦!

猜你喜欢

转载自blog.csdn.net/weixin_42940826/article/details/82533840