golang判断net.Conn 是否已关闭?

6 篇文章 0 订阅

在多线程的线程里边,用一个线程处理一条连接,如何判断连接已经关闭?
试了一下,如果连接中断,读写会出现这种net.OpError,这个就可以判断是否断开
但是我也不确定有没有更好的方法?如果有的话,希望朋友们不吝赐教


func dealConn(conn net.Conn){
	//defer conn.Close()
	//defer conn.Flush()
    //长连接里边的读写操作必须放到循环里面这样才能进行多次的读写
    // 如果连接已经断开,就把这个线程中断掉,怎么判断这个连接已经断开?    
    thread_c:=0;//如果连续100秒中读取不到内容,就终止循环
    for{
        defer func() {
            if r := recover(); r != nil {
                buf:=make([]byte,666)
                buf=buf[:runtime.Stack(buf,false)]
                log.Printf("运行时错误:%v.Runtime error caught: %s",r, buf)
            }
        }()
        // 注意continue这里也要等待,不然造成内存耗尽,处理器耗尽
        time.Sleep(50*time.Millisecond)
        //#log.Println(len,string(text))
        thread_c++
        if thread_c>20*100{
        	log.Println(conn.RemoteAddr(),"超过100秒未读取到内容,本连接将关闭")
        	conn.Close();
        	c--;
        	break;
        }
        frame,op_err:=readAllShut(conn)
        if op_err!=nil{
        	log.Println(conn.RemoteAddr(),"出现读写错误,连接不可用,将会被关闭")
        	conn.Close();
        	c--;
        	break;//这种已经关闭的连接,要终止循环,退出这条线程
        }
        if(len(frame)==0){
        	//
        	//time.Sleep(50*time.Millisecond)
            continue
        }
        thread_c=0;
        log.Printf("-----------------收到tcp请求:报文的长度是%v,详细内容如下:%s,转换成16进制是:%x", len(frame),frame,frame)
        //TODO
        //这里写自己的业务代码
        }
   }

func readAllShut(conn net.Conn) ([]byte,error){	//这个手动方法可以避免粘包的问题
	//bufio.NewWriter
	re:=bytes.NewBuffer(nil)
	const N=666
	for{
		var text [N]byte
		lens,err:=conn.Read(text[0:])
		re.Write(text[:lens])
		if lens==0 || err!=nil{
			//log.Println(err)  //在这个死循环里面,不要有任何的输出
			// if errors.As(err,*net.OpError) 	//
			if _,ok:=err.( *net.OpError) ;ok{		
				return nil,err
			}
			break
		}
		//conn
		//log.Println(lens,text)
		if lens<N{
			break
		}
	}
	rb:= re.Bytes()
	//log.Println(rb,"len",len(rb))
	return rb,nil
	/*data,err:=ioutil.ReadAll(conn)
	if err!=nil{
		log.Printf("读取出现错误%T:%v",err,err)
	}
	return data;*/
}   
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值