简易tcp服务器,send on closed channel优化请教

zhjzjnb · · 669 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

#### 简单实现了一个echo服务器 #### 对于每个链接,封装了一个TcpConn处理,并且开了4个goroutine处理分别处理读、写、逻辑、关闭(据说goroutine开销很小,一对4的关系有问题么) #### 现在的问题是逻辑代码中,因为一些操作延迟,导致sendChan被关闭,所以不得不再加了关闭锁的判断,有什么办法优化么 ```go package main import ( "log" "net" "sync" "time" ) type TcpConn struct { conn net.Conn dataChan chan []byte sendChan chan []byte closeChan chan bool closeFlag bool closeLock sync.Mutex } func (self *TcpConn) send() { for buff := range self.sendChan { _, err := self.conn.Write(buff) if err != nil { log.Println("send error", err) break } } self.close() } func (self *TcpConn) recv() { tmp := make([]byte, 1024) for { len, err := self.conn.Read(tmp) if err != nil { log.Println("recv error", err) break } data := make([]byte, len) copy(data, tmp[:len]) self.dataChan <- data } self.close() } func (self *TcpConn) doLogic() { for b := range self.dataChan { time.Sleep(1500 * time.Millisecond) //加了这个关闭判断,不然会报错 send on closed channel //if self.closeFlag { // return //} //self.closeLock.Lock() //if self.closeFlag { // return //} //self.closeLock.Unlock() self.sendChan <- b } } func (self *TcpConn) close() { if self.closeFlag { return } self.closeLock.Lock() defer self.closeLock.Unlock() if self.closeFlag { return } self.closeFlag = true self.closeChan <- true } func main() { listener, err := net.Listen("tcp", "0.0.0.0:7788") if err != nil { log.Fatal("run err", err) } log.Println("server run at 7788") defer listener.Close() for { conn, err := listener.Accept() if err != nil { log.Fatal("accept err", err) } log.Println("one connect come") client := &TcpConn{ conn: conn, dataChan: make(chan []byte), sendChan: make(chan []byte), closeChan: make(chan bool), closeFlag: false, closeLock: sync.Mutex{}, } go func() { go client.send() go client.recv() go client.doLogic() select { case <-client.closeChan: log.Println("close net.Conn") conn.Close() } close(client.closeChan) close(client.dataChan) close(client.sendChan) log.Println("one tcp end") }() } } ```

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

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

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