Интерфейс net.Conn
Интерфейс net.Conn является основным интерфейсом для работы с сетевыми соединениями в Go. Он представляет собой двунаправленный поток данных между двумя узлами сети. Интерфейс реализует методы для чтения, записи, закрытия соединения, а также получения информации о локальном и удаленном адресах. net.Conn реализуется типами net.TCPConn, net.UDPConn и net.UnixConn.
Синтаксис
type Conn interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
Close() error
LocalAddr() Addr
RemoteAddr() Addr
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
}
Методы интерфейса
Интерфейс net.Conn предоставляет следующие методы:
-
Read- читает данные из соединения в переданный срез байтов и возвращает количество прочитанных байтов; -
Write- записывает данные из среза байтов в соединение и возвращает количество записанных байтов; -
Close- закрывает соединение, освобождая связанные с ним ресурсы; -
LocalAddr- возвращает локальный адрес соединения; -
RemoteAddr- возвращает удаленный адрес соединения; -
SetDeadline- устанавливает абсолютный таймаут для всех операций ввода-вывода; -
SetReadDeadline- устанавливает таймаут для операций чтения; -
SetWriteDeadline- устанавливает таймаут для операций записи.
Пример чтения данных из соединения
Давайте создадим TCP-сервер, который принимает соединение и читает данные от клиента:
package main
import (
"fmt"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Error listening:", err)
return
}
defer listener.Close()
go func() {
time.Sleep(100 * time.Millisecond)
conn, err := net.Dial("tcp", ":8080")
if err != nil {
fmt.Println("Error dialing:", err)
return
}
defer conn.Close()
conn.Write([]byte("Hello, Server!"))
}()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting:", err)
return
}
defer conn.Close()
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Println(string(buf[:n]))
}
Результат выполнения кода:
"Hello, Server!"
Пример записи данных в соединение
Давайте отправим данные клиенту в ответ на его запрос:
package main
import (
"fmt"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", ":8081")
if err != nil {
fmt.Println("Error listening:", err)
return
}
defer listener.Close()
go func() {
time.Sleep(100 * time.Millisecond)
conn, err := net.Dial("tcp", ":8081")
if err != nil {
fmt.Println("Error dialing:", err)
return
}
defer conn.Close()
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Println(string(buf[:n]))
}()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting:", err)
return
}
defer conn.Close()
_, err = conn.Write([]byte("Hello, Client!"))
if err != nil {
fmt.Println("Error writing:", err)
return
}
}
Результат выполнения кода:
"Hello, Client!"
Пример установки таймаута
Давайте установим таймаут на чтение данных из соединения:
package main
import (
"fmt"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", ":8082")
if err != nil {
fmt.Println("Error listening:", err)
return
}
defer listener.Close()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting:", err)
return
}
defer conn.Close()
conn.SetReadDeadline(time.Now().Add(1 * time.Second))
buf := make([]byte, 1024)
_, err = conn.Read(buf)
if err != nil {
fmt.Println(err)
return
}
}
Результат выполнения кода (при отсутствии данных в течение 1 секунды):
"read tcp 127.0.0.1:8082->127.0.0.1:12345: i/o timeout"
Пример получения адресов соединения
Давайте получим локальный и удаленный адреса соединения:
package main
import (
"fmt"
"net"
"time"
)
func main() {
listener, err := net.Listen("tcp", ":8083")
if err != nil {
fmt.Println("Error listening:", err)
return
}
defer listener.Close()
go func() {
time.Sleep(100 * time.Millisecond)
conn, err := net.Dial("tcp", ":8083")
if err != nil {
fmt.Println("Error dialing:", err)
return
}
defer conn.Close()
}()
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting:", err)
return
}
defer conn.Close()
localAddr := conn.LocalAddr().String()
remoteAddr := conn.RemoteAddr().String()
fmt.Println("Local address:", localAddr)
fmt.Println("Remote address:", remoteAddr)
}
Результат выполнения кода:
"Local address: [::]:8083"
"Remote address: [::1]:12346"
Смотрите также
-
интерфейс
net.Listener,
который используется для прослушивания входящих подключений -
структуру
net.Dialer,
которая управляет параметрами установки соединения -
тип
net.TCPConn,
который реализует интерфейсnet.Connдля TCP-соединений -
тип
net.UDPConn,
который реализует интерфейсnet.Connдля UDP-соединений