围棋TCP读的是非阻塞 [英] Go TCP read is non blocking

查看:234
本文介绍了围棋TCP读的是非阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使围棋的服务器和客户端,我设法与服务器和客户端进行通信。不过,我的问题是,在golang阅读TCP是非阻塞的。
我想知道,如果有可能在golang读来会阻止像阅读C.
谢谢

编辑:

下面是服务器的源$ C ​​$ C:

  FUNC Init_tcp()* net.TCPListener {
    LADDR,ERR:= net.ResolveTCPAddr(TCP,:4243)
    如果犯错!= {为零
            log.Fatal(ERR)
    }
    TCP,ERR:= net.ListenTCP(TCP,LADDR)
    如果犯错!= {为零
            log.Fatal(ERR)
    }
    TCP回报
}FUNC的main(){
    TCP:= Init_tcp()
    康涅狄格州,_:= tcp.Accept()
    数据:=令([]字节,512)
    conn.SetNoDelay(假)
    为{
            conn.Read(数据)
            fmt.Println(数据)
    }
}

和我的客户:

  FUNC Init_tcp()* net.TCPConn {
    LADDR,ERR:= net.ResolveTCPAddr(TCP,127.0.0.1:4243)
    如果犯错!= {为零
            log.Fatal(ERR)
    }
    TCP,ERR:= net.DialTCP(TCP,零,LADDR)
    如果犯错!= {为零
            log.Fatal(ERR)
    }
    TCP回报
}FUNC的main(){
   TCP:= Init_tcp()
   tcp.Write([]字节(世界你好))
}


解决方案

阅读 s时,可以恢复部分数据。从的文档,如果某些数据是可用的,但不是LEN(P)字节,传统阅读返回什么是可用的,而不是等待更多。

这是在任何语言的问题,即使像这样的事情在C的工作:TCP只是提供了一个可以写入任何时候字节流。单写会按照设计,被分解成传输多个数据包,并没有内置的信号接收器说在一个单一的写/消息/请求结​​束。应用程序必须找出自己的路信号的界限。这可能意味着分隔符( \\ n )隐性或显性的字节数或(HTTP的的Content-Length 是一个明确的)

要读取输入字节的具体数量,你想 io.ReadAtLeast io.ReadFull 。要阅读一些之前任意条件满足你应该只在读循环拨打只要没有错误。 (那你可能需要从饮食服务器资源报错了对过大的输入prevent一个糟糕的客户端。)如果你正在实施一个基于文本的协议,你应该考虑的 网​​/ textproto ,这使一个的 bufio.Reader 在连接的前面,因此你可以读线。要限制你会等多久才能读完(这样一个行为不端的客户端不能留下够程悬挂和使用内存等永远),看的 在名称截止日期的功能(这是有关超时功能在错误类型)。

(样品code有可能是无关的,但重要的问题:它从。这可能占部分读取后,面膜简单的问题,使他们很难调试。如果你有问题,要求更多帮助前先检查所有错误。再看的 errcheck 以确保犯错误这样不进入生产。)

I am trying to make a server and client in Go, I have managed to communicate with the server and client. But the problem I have is that the TCP read in golang is non-blocking. What I would like to know if is it possible for the read in golang to be blocking like read in C. Thank You

EDIT:

Here is the source code of the server:

func Init_tcp() *net.TCPListener {
    laddr, err := net.ResolveTCPAddr("tcp", ":4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.ListenTCP("tcp", laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
    tcp := Init_tcp()
    conn, _ := tcp.Accept()
    data := make([]byte, 512)
    conn.SetNoDelay(false)
    for {
            conn.Read(data)
            fmt.Println(data)
    }
}

and my client:

func Init_tcp() *net.TCPConn {
    laddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:4243")
    if err != nil {
            log.Fatal(err)
    }
    tcp, err := net.DialTCP("tcp", nil, laddr)
    if err != nil {
            log.Fatal(err)
    }
    return tcp
}

func main() {
   tcp := Init_tcp()
   tcp.Write([]byte("hello world"))
}

解决方案

Readers can return partial data. From the docs, "If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more."

This is an issue in any language, even if something like this happened to work for you in C: TCP just provides a stream of bytes that can be written to any time. Single writes might, by design, be broken up into multiple packets for transmission, and there's no built-in signal to the receiver saying where a single write/message/request ends. The application has to figure out its own way to signal boundaries. That can mean delimiters (\n) or implicit or explicit byte counts (HTTP's Content-Length is an explicit one).

To read a specific number of input bytes, you want io.ReadAtLeast or io.ReadFull. To read until some arbitrary condition is met you should just loop on the Read call as long as there is no error. (Then you may want to error out on on too-large inputs to prevent a bad client from eating server resources.) If you're implementing a text-based protocol you should consider net/textproto, which puts a bufio.Reader in front of the connection so you can read lines. To limit how long you'll wait to finish reading (so that a misbehaving client can't leave a goroutine hanging and using memory, etc. forever), look at the net functions with Deadline in the name (which are related to the Timeout functions on the Error types).

(The sample code has a possibly unrelated but important problem: it throws away errors from the Read and Write. That could mask simple problems and make them very hard to debug. If you have problems after accounting for partial reads, check all errors before asking for more help. Look at errcheck to make sure mistakes like this don't get into production.)

这篇关于围棋TCP读的是非阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆