[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 ...
随机推荐
- CodeForces - 1221E Game With String(不平等博弈)
Alice and Bob play a game. Initially they have a string s1,s2,…,sns1,s2,…,sn, consisting of only cha ...
- POJ3261 Milks patterns(后缀数组)
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On furthe ...
- (全国多校重现赛一) H Numbers
zk has n numbers a1,a2,...,ana1,a2,...,an. For each (i,j) satisfying 1≤i<j≤n, zk generates a new ...
- ARTS-S mongo关闭与启动
关闭 mongo admin --eval "db.shutdownServer()" 删除dbdata目录下的mongo.lock 启动 /usr/bin/mongod --db ...
- stm32 io操作 头文件规范
在stm32众多项目开发中,有太多的对io进行操作,若置1或清0,使用官方库提供的函数,固然方便,规范,但是需要包含标准的库,尺寸较大,还得处理不同版本兼容问题,包括io初始化也太繁琐,于是操作原子等 ...
- Python流程控制之分支结构
目录 if/else结构 多重if结构 嵌套if结构 练习 if/else结构 if如果,else否则 # java if(){ }else{ } # python if 条件: 语句 else: 语 ...
- 大数据学习笔记——Hadoop高可用完全分布式模式完整部署教程(包含zookeeper)
高可用模式下的Hadoop集群搭建 本篇博客将会在之前写过的Linux的完整部署的基础上进行,暂时不会涉及到伪分布式或者完全分布式模式搭建,由于HA模式涉及到的配置文件较多,维护起来也较为复杂,相信学 ...
- 10分钟理解BFC原理
10 分钟理解 BFC 原理 一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照 ...
- 封装读取文件(node js)
我们都会简单的读取文件,今天我们就来讲一下用函数封装读取文件. 1.首先我们要先建好文件 2.我们在index.js里面写入代码: var http=require('http'); var fs=r ...
- poj 1270 Following Orders (拓扑排序+回溯)
Following Orders Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5473 Accepted: 2239 ...