去TCP读取是非阻塞的

问题描述:

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"))
}

我正在尝试在Go中制作服务器和客户端,我已经设法与服务器和客户端进行通信。 但是我的问题是golang中的TCP读取是非阻塞的。 我想知道golang中的读取是否有可能像C中的读取一样被阻塞。 谢谢 p>

编辑: p>

这是服务器的源代码: p>

  func Init_tcp()* net.TCPListener {  
 laddr,err:= net.ResolveTCPAddr(“ tcp”,“:4243”)
如果err!= nil {
 log.Fatal(err)
} 
 tcp,err:= net.ListenTCP(  “ tcp”,laddr)
如果错误!= nil {
 log.Fatal(err)
} 
返回tcp 
} 
 
func main(){
 tcp:= Init_tcp()
  conn,_:= tcp.Accept()
 data:= make([] byte,512)
 conn.SetNoDelay(false)
 for {
 conn.Read(data)
 fmt.Println(data  )
} 
} 
  code>  pre> 
 
 

和我的客户端: p>

  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)
如果是 r!= nil {
 log.Fatal(err)
} 
返回tcp 
} 
 
func main(){
 tcp:= Init_tcp()
 tcp.Write([] byte(“ 你好世界“))
} 
  code>  pre> 
  div>

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 ( ) 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 context package helps manage timeouts, deadlines, and cancellation, and is especially useful if, for example, you're writing a complex server that's going to do many network operations every request.

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.