The difference between listening, reading and writing in a network packet

I am new to Go, and as one of my first test projects, I would like to write a simple client-server program using UDP. I got it to work, but there are many ways to do this, and I would like to know that this is the best way.

net.Listen () vs net.ListenUDP () vs net.ListenPacket ()

net.Read () vs net.ReadFrom () vs net.ReadFromUDP ()

net.Write () vs net.WriteTo () vs net.WriteToUDP ()

+8
source share
2 answers

Let's consider your question.

1. net.Listen () vs net.ListenUDP () vs net.ListenPacket ()

net.Listen ()

Listen to announcements on the local network at laddr. The network should be a flow-oriented network: tcp, tcp4, tcp6, unix, or unixpacket. See Dial for laddr syntax.

Example of use No. 1:

tcpSock, err := net.Listen("tcp", "0.0.0.0:8080") 

Case Study # 2

 unixSock, err := net.Listen("unix", "/var/app/server.sock") 

From the source net.Listen() that net.Listen() works like a switch statement that calls either net.ListenTCP or net.ListenTCP or net.ListenUnix by default:

 func Listen(net, laddr string) (Listener, error) { la, err := resolveAddr("listen", net, laddr, noDeadline) if err != nil { return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} } var l Listener switch la := la.toAddr().(type) { case *TCPAddr: l, err = ListenTCP(net, la) case *UnixAddr: l, err = ListenUnix(net, la) default: return nil, &OpError{ Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}, } } if err != nil { return nil, err // l is non-nil interface containing nil pointer } return l, nil } 

Additional information at net.Listen () Docs

So, we can exclude net.ListenUDP from the initial comparison; and look at net.ListenPacket() .

net.ListenPacket ()

ListenPacket announces the laddr address on the local network. The network should be a packet-oriented network: udp, udp4, udp6, ip, ip4, ip6, or unixgram. See Dial for laddr syntax.

Example of use No. 1:

 pListener, err := net.ListenPacket("ip4", "0.0.0.0:9090") 

And, if we look inside, we will see that it works almost the same as net.Listen() :

 func ListenPacket(net, laddr string) (PacketConn, error) { la, err := resolveAddr("listen", net, laddr, noDeadline) if err != nil { return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} } var l PacketConn switch la := la.toAddr().(type) { case *UDPAddr: l, err = ListenUDP(net, la) case *IPAddr: l, err = ListenIP(net, la) case *UnixAddr: l, err = ListenUnixgram(net, la) default: return nil, &OpError{ Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}, } } if err != nil { return nil, err // l is non-nil interface containing nil pointer } return l, nil } 

2. net.Read () vs net.ReadFrom () vs net.ReadFromUDP ()

As expected, these functions are used to read from various net connections.

net.Read ()

If you look at the network packet, you will see that all Read() functions come from types that implement the Conn interface.

A Conn interface is defined as:

... shared streaming network connection.

To implement net.Conn you need to have the following methods:

 type Conn interface { // Read reads data from the connection. // Read can be made to time out and return a Error with Timeout() == true // after a fixed time limit; see SetDeadline and SetReadDeadline. Read(b []byte) (n int, err error) // Write writes data to the connection. // Write can be made to time out and return a Error with Timeout() == true // after a fixed time limit; see SetDeadline and SetWriteDeadline. Write(b []byte) (n int, err error) // Close closes the connection. // Any blocked Read or Write operations will be unblocked and return errors. Close() error // LocalAddr returns the local network address. LocalAddr() Addr // RemoteAddr returns the remote network address. RemoteAddr() Addr // SetDeadline sets the read and write deadlines associated // with the connection. It is equivalent to calling both // SetReadDeadline and SetWriteDeadline. // // A deadline is an absolute time after which I/O operations // fail with a timeout (see type Error) instead of // blocking. The deadline applies to all future I/O, not just // the immediately following call to Read or Write. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful Read or Write calls. // // A zero value for t means I/O operations will not time out. SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error // SetWriteDeadline sets the deadline for future Write calls. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. // A zero value for t means Write will not time out. SetWriteDeadline(t time.Time) error } 

Source

So this should make it clear that there is actually no net.Read() ; but, rather, Read() functions that work with types that implement the net.Conn interface.

net.ReadFrom ()

As with net.Read (), all implementations come from an interface implementation. In this case, this interface is net.PacketConn

PacketConn is a standard packet-oriented network connection.

 type PacketConn interface { // ReadFrom reads a packet from the connection, // copying the payload into b. It returns the number of // bytes copied into b and the return address that // was on the packet. // ReadFrom can be made to time out and return // an error with Timeout() == true after a fixed time limit; // see SetDeadline and SetReadDeadline. ReadFrom(b []byte) (n int, addr Addr, err error) // WriteTo writes a packet with payload b to addr. // WriteTo can be made to time out and return // an error with Timeout() == true after a fixed time limit; // see SetDeadline and SetWriteDeadline. // On packet-oriented connections, write timeouts are rare. WriteTo(b []byte, addr Addr) (n int, err error) // Close closes the connection. // Any blocked ReadFrom or WriteTo operations will be unblocked // and return errors. Close() error // LocalAddr returns the local network address. LocalAddr() Addr // SetDeadline sets the read and write deadlines associated // with the connection. SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls. // If the deadline is reached, Read will fail with a timeout // (see type Error) instead of blocking. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error // SetWriteDeadline sets the deadline for future Write calls. // If the deadline is reached, Write will fail with a timeout // (see type Error) instead of blocking. // A zero value for t means Write will not time out. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. SetWriteDeadline(t time.Time) error } 

Note: TCPConn.ReadFrom comes from the implementation of the iF.ReaderFrom ReadFrom method.

3.net.Write ()

As you may have guessed, we are looking at the same model again and again. This is called an interface implementation. I will leave you to look at this particular method and how it works, using the above explanation as a roadmap.

It's best to first look at the Effective Go parts about interfaces .

More information about the net package is available at source and GoDoc

+20
source

If you work only with UDP packets, the best solution is to use UDP functions.

net.ListenUDP () can, for example, listen to the udp, udp4, and udp6 packets. net.ListenPacket can listen to all UDP packets, but also for ip, ip4, ip6 and unixgram packets. net.Listen () can listen on tcp, tcp4, tcp6, unix and unixpacket packets.

Source: http://golang.org/pkg/net/

0
source

Source: https://habr.com/ru/post/972761/


All Articles