分享
  1. 首页
  2. 文章

golang 简易聊天

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

client.go
------------------------------
package main
import (
 "net"
 "fmt"
 "bufio"
 "echo/codec"
 "time"
)
var quitSemaphore chan bool
func main() {
 var tcpAddr *net.TCPAddr
 tcpAddr,_=net.ResolveTCPAddr("tcp","127.0.0.1:9999")
 conn,_:=net.DialTCP("tcp",nil,tcpAddr) //开启连接
 defer conn.Close() //关闭连接
 fmt.Println("Connected!")
 go onMessageRecived(conn) //接收消息
 go sendMessage(conn) //发送消息
 <-quitSemaphore
}
// 发送消息
func sendMessage(conn *net.TCPConn) {
 //发送消息
 for{
 time.Sleep(1 * time.Second)
 var msg string
 fmt.Scanln(&msg)
 if msg == "quit"{
 quitSemaphore <- true
 break
 }
 //lk
 //b :=[]byte(msg +"\n")
 //处理加密
 b ,_ := codec.Encode(msg+"\n")
 conn.Write(b)
 }
}
server.go
-----------------------------
package main
import (
 "bufio"
 "fmt"
 "net"
 "echo/codec"
)
// 用来记录所有的客户端连接
var ConnMap map[string]*net.TCPConn
func main() {
 var tcpAddr *net.TCPAddr
 ConnMap = make(map[string]*net.TCPConn) //初始化
 tcpAddr,_=net.ResolveTCPAddr("tcp","127.0.0.1:9999")
 tcpListener,_:=net.ListenTCP("tcp",tcpAddr) //开启tcp 服务
 //退出时关闭
 defer tcpListener.Close()
 for{
 tcpConn,err :=tcpListener.AcceptTCP()
 if err !=nil {
 continue
 }
 fmt.Println("A client connected : "+ tcpConn.RemoteAddr().String())
 // 新连接加入 map
 ConnMap[tcpConn.RemoteAddr().String()] = tcpConn
 go tcpPipe(tcpConn)
 }
}
//处理发送过来的消息
func tcpPipe(conn *net.TCPConn) {
 ipStr :=conn.RemoteAddr().String()
 defer func() {
 fmt.Println("disconnected : "+ ipStr)
 conn.Close()
 }()
 //读取数据
 reader :=bufio.NewReader(conn)
 for {
 message ,err :=codec.Decode(reader)//reader.ReadString('\n')
 if err != nil {
 return
 }
 fmt.Println(string(message))
 //这里返回消息改为广播
 boradcastMessage(conn.RemoteAddr().String()+":"+string(message))
 }
}
//广播给其它 
func boradcastMessage(message string) {
 //遍历所有客户端并发消息
 for _,conn :=range ConnMap{
 b,err :=codec.Encode(message)
 if err != nil {
 continue
 }
 conn.Write(b)
 }
}
codec.go
------------------------
package codec
import (
 "bytes"
 "encoding/binary"
 "bufio"
)
func Encode(message string) ([]byte, error) {
 // 读取消息的长度
 var length int32 = int32(len(message))
 var pkg *bytes.Buffer = new(bytes.Buffer)
 // 写入消息头
 err := binary.Write(pkg, binary.LittleEndian, length)
 if err != nil {
 return nil, err
 }
 // 写入消息实体
 err = binary.Write(pkg, binary.LittleEndian, []byte(message))
 if err != nil {
 return nil, err
 }
 return pkg.Bytes(), nil
}
func Decode(reader *bufio.Reader) (string, error) {
 // 读取消息的长度
 lengthByte, _ := reader.Peek(4)
 lengthBuff := bytes.NewBuffer(lengthByte)
 var length int32
 err := binary.Read(lengthBuff, binary.LittleEndian, &length)
 if err != nil {
 return "", err
 }
 if int32(reader.Buffered()) < length+4 {
 return "", err
 }
 // 读取消息真正的内容
 pack := make([]byte, int(4+length))
 _, err = reader.Read(pack)
 if err != nil {
 return "", err
 }
 return string(pack[4:]), nil
}
func onMessageRecived(conn *net.TCPConn) {
 reader :=bufio.NewReader(conn)
 for {
 //解密
 msg,err := codec.Decode(reader)//reader.ReadString('\n')
 fmt.Println(msg)
 if err !=nil {
 quitSemaphore <- true
 break
 }
 }
}

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

本文来自:博客园

感谢作者:jackluo

查看原文:golang 简易聊天

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

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

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏