go实现的简易TCP的客户端和服务器

徐学良 · · 8792 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

今天介绍golang版本的通信基础:基于TCP的客户端和服务器实现,参考书籍:The Way To Go

那时学习java的时候也是做过通信的,当时是socket编程,服务器监听某一个端口,然后客户机去连接,简单的聊天室就实现了。后来有变成多线程的聊天室,可以进行群聊什么的了,后期可以传图片传音乐,加上UI那一块儿,山寨QQ就OK了。现在我来用golang实现一下简易的聊天室,实现了客户机连接服务器,给服务器发消息,服务器接受消息,客户机退出,服务器可以收到退出信息,以及多个客户机同时连入一个服务器。主要的思路和java一样的,服务器监听某一个端口,客户机去连接,然后发送消息就OK了。上代码了。
package main

//服务器端
import (
    "fmt"
    "log"
    "net" //支持通讯的包
)

//开始服务器
func startServer() {
    //连接主机、端口,采用tcp方式通信,监听7777端口
    listener, err := net.Listen("tcp", "localhost:7777")
    checkError(err)
    fmt.Println("建立成功!")
    for {
        //等待客户端接入
        conn, err := listener.Accept()
        checkError(err)
        //开一个goroutines处理客户端消息,这是golang的特色,实现并发就只go一下就好
        go doServerStuff(conn)
    }
}

//处理客户端消息
func doServerStuff(conn net.Conn) {
    nameInfo := make([]byte, 512) //生成一个缓存数组
    _, err := conn.Read(nameInfo)
    checkError(err)

    for {
        buf := make([]byte, 512)
        _, err := conn.Read(buf) //读取客户机发的消息
        flag := checkError(err)
        if flag == 0 {
            break
        }
        fmt.Println(string(buf)) //打印出来
    }
}

//检查错误
func checkError(err error) int {
    if err != nil {
        if err.Error() == "EOF" {
            //fmt.Println("用户退出了")
            return 0
        }
        log.Fatal("an error!", err.Error())
        return -1
    }
    return 1
}
func main() {
    //开启服务
    startServer()
}

 以上是服务器的实现,具体看代码注释
package main

//客户机
import (
    "bufio"
    "fmt"
    "log"
    "net"
    "os"
    "strings"
)

//连接服务器
func connectServer() {
    //接通
    conn, err := net.Dial("tcp", "localhost:7777")
    checkError(err)
    fmt.Println("连接成功!\n")
    //输入
    inputReader := bufio.NewReader(os.Stdin)
    fmt.Println("你是谁?")
    name, _ := inputReader.ReadString('\n')
    //
    trimName := strings.Trim(name, "\r\n")
    conn.Write([]byte(trimName + " 接入了\n "))
    for {
        fmt.Println("我们来聊天吧!按quit退出")
        //读一行
        input, _ := inputReader.ReadString('\n')
        trimInput := strings.Trim(input, "\r\n")
        //如果quit就退出
        if trimInput == "quit" {
            fmt.Println("再见")
            conn.Write([]byte(trimName + " 退出了 "))
            return
        }
        //写出来
        _, err = conn.Write([]byte(trimName + " says " + trimInput))
    }
}

//检查错误
func checkError(err error) {
    if err != nil {
        log.Fatal("an error!", err.Error())
    }
}

//主函数
func main() {
    //连接servser
    connectServer()
}

 以上是客户机代码,具体看注释

运行的时候,分别go run server和client,你变可以看到这样就可以连接成功了。
 服务器只用开一个,客户机可以开任意个,并且相互之间没有干扰。

OK,一个简单的多线程聊天室就实现了。后期可以加上更多的功能,但无非就是去处理输入输出,重点都已经有了。

--------------------------------------------------------------------------------

欢迎提出建议!


有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:徐学良

查看原文:go实现的简易TCP的客户端和服务器

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

8792 次点击  ∙  1 赞  
加入收藏 微博
1 回复  |  直到 2018-06-05 22:21:45
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传