[Go]TCP服务中读写进行协程分离
读写两部分进行一下分离,中间通过chan进行传递数据 ,这样可以方便的在write中进行一些业务处理
single/snet/tcpconn.go
package snet import (
"bufio"
"fmt"
"log"
"net"
) type Conn struct {
IP string
Port uint32
TCPConn *net.TCPConn
MsgChan chan []byte
ExitChan chan bool
Closed bool
} func NewConn(IP string, Port uint32) *Conn {
s := &Conn{
IP: IP,
Port: Port,
MsgChan:make(chan []byte),
ExitChan: make(chan bool),
}
return s
} func (c *Conn) Start() {
log.Printf("%s:%d start...\n", c.IP, c.Port)
go func() {
addr, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf("%s:%d", c.IP, c.Port))
if err != nil {
log.Println("resolve tcp addr err ", err)
return
}
listener, err := net.ListenTCP("tcp4", addr)
if err != nil {
log.Println("listen tcp err ", err)
return
}
var connid uint32
connid =
for {
conn, err := listener.AcceptTCP()
if err != nil {
log.Println("accept tcp err ", err)
continue
}
c.TCPConn = conn
go c.StartRead()
go c.StartWrite()
connid++
}
}()
select {}
}
func (c *Conn) StartRead() {
log.Println("read groutine is waiting")
defer c.Stop()
defer log.Println("read groutine exit")
reader := bufio.NewReader(c.TCPConn)
for {
lineBytes, err := reader.ReadBytes('\n')
if err != nil {
log.Println("startread read bytes error ", err)
break
}
len:=len(lineBytes)
line:=lineBytes[:len-]
log.Println("start read from client ",string(line))
go c.HandleMsg(line)
}
}
func (c *Conn) StartWrite() {
log.Println("write groutine is waiting")
defer log.Println("write groutine exit")
for {
select {
case data := <-c.MsgChan:
if _, err := c.TCPConn.Write(data); err != nil {
log.Println("startwrite conn write error ", err)
return
}
log.Println("start write from server ",string(data))
case <-c.ExitChan:
return
}
}
}
func (c *Conn) HandleMsg(data []byte) {
res := fmt.Sprintf("res:%s", string(data)) c.MsgChan <- []byte(res)
}
func (c *Conn) Stop() {
if c.Closed {
return
}
c.Closed = true
c.ExitChan <- true c.TCPConn.Close()
close(c.ExitChan)
close(c.MsgChan)
}
测试代码,使用上面的包:
server.go
package main import "single/snet"
func main(){
s:=snet.NewConn("0.0.0.0",)
s.Start()
}
[Go]TCP服务中读写进行协程分离的更多相关文章
- 038_go语言中的状态协程
代码演示: package main import ( "fmt" "math/rand" "sync/atomic" "time ...
- yield学习续:yield return迭代块在Unity3D中的应用——协程
必读好文推荐: Unity协程(Coroutine)原理深入剖析 Unity协程(Coroutine)原理深入剖析再续 上面的文章说得太透彻,所以这里就记一下自己的学习笔记了. 首先要说明的是,协程并 ...
- Unity中巧用协程和游戏对象的生命周期处理游戏重启的问题
主要用到协程(Coroutines)和游戏对象的生命周期(GameObject Lifecycle)基础知识,巧妙解决了游戏重启的问题. 关于协程,这里有篇文章我觉得写的非常好,理解起来也很容易.推荐 ...
- python中线程 进程 协程
多线程:#线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释器锁#只要在进行耗时的IO操作的 ...
- Android中的Coroutine协程原理详解
前言 协程是一个并发方案.也是一种思想. 传统意义上的协程是单线程的,面对io密集型任务他的内存消耗更少,进而效率高.但是面对计算密集型的任务不如多线程并行运算效率高. 不同的语言对于协程都有不同的实 ...
- python编程中的并发------协程gevent模块
任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...
- [Go]TCP服务中增加消息队列与工作池
之前的处理中每一个连接都会创建一个主groutine , 每个连接中的主groutine中创建出读groutine 和写groutine 每个连接处理业务再单独开出一个groutine ,这样如果有1 ...
- Python中进程线程协程小结
进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...
- main函数中如何等待协程运行完毕
使用channel同步 package main import ( "fmt" ) func printNumber(num int, c chan struct{}) { fmt ...
随机推荐
- OSC2019关于开源的见闻-开源让世界更美好 社会更文明
一.开源生态报告-红薯-开源中国创始人 1.协作乏力-大厂同样 2.协议许可证使用不当 新许可证-木兰 3.开发者对法律认识完全不够 著作权意识不够 红线意识不够 相关法律法规的熟悉不够 维权及其弱势 ...
- 用span写一个特殊样式的1
用span写一个如下样式的 1 span { display: inline-block; width: 17px; height: 17px; background: var(--themeColo ...
- Java类中static的用法
关于Java中static的使用有以下四种情况: 1.静态成员变量 被static修饰的成员变量,叫静态成员变量或类变量:没有被static修饰的变量,叫实例变量. 两者的区别是: ...
- final关键字、finally代码块和finalize()方法有什么区别?
1. final是关键字,final可以修饰类.方法.属性. 如果一个类被final修饰,那么这个类就是最终类,不能派生出新的子类,不能作为父类被继承,该类中的所有方法都不能被重写,但是final类中 ...
- django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询
from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...
- Common Lisp学习资源整理
Lisp Hackers: Interviews with 100x More Productive Programmers Posted on June 26th, 2013 Lisp Hacker ...
- 基于 TrueLicense 的项目证书验证
一.简述 开发的软件产品在交付使用的时候,往往有一段时间的试用期,这期间我们不希望自己的代码被客户二次拷贝,这个时候 license 就派上用场了,license 的功能包括设定有效期.绑定 ip.绑 ...
- SSM整合框架(基于IDEA的配置)
Pom文件 <?xml version="1.0" encoding="UTF-8"?><project xmlns="http:/ ...
- UWP 利用Windows.UI.Composition实现简单的放大🔍效果
看一下效果先 我这里实现了鼠标进入和退出的效果,当然也可以添加其他的事件,比如获得焦点和失去焦点的. 先随便写一个xaml布局,一个Grid,里面一张图片. <Grid x:Name=" ...
- Blockchain 基本知识
本文是前奏,本来要介绍Azure上的Azure Blockchain Service,发现,需要从什么是区块链开始讲起... 什么是区块链?我们从比特币说起, 2008年11月,中本聪提出了比特币白皮 ...