Интерфейс net.Conn

Интерфейс net.Conn является основным интерфейсом для работы с сетевыми соединениями в Go. Он представляет собой двунаправленный поток данных между двумя узлами сети. Интерфейс реализует методы для чтения, записи, закрытия соединения, а также получения информации о локальном и удаленном адресах. net.Conn реализуется типами net.TCPConn, net.UDPConn и net.UnixConn.

Синтаксис

gotype 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 предоставляет следующие методы:

Пример чтения данных из соединения

Давайте создадим TCP-сервер, который принимает соединение и читает данные от клиента:

gopackage 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]))
}

Результат выполнения кода:

go"Hello, Server!"

Пример записи данных в соединение

Давайте отправим данные клиенту в ответ на его запрос:

gopackage 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
  }
}

Результат выполнения кода:

go"Hello, Client!"

Пример установки таймаута

Давайте установим таймаут на чтение данных из соединения:

gopackage 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 секунды):

go"read tcp 127.0.0.1:8082->127.0.0.1:12345: i/o timeout"

Пример получения адресов соединения

Давайте получим локальный и удаленный адреса соединения:

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

Результат выполнения кода:

go"Local address: [::]:8083"
"Remote address: [::1]:12346"

Смотрите также

  • интерфейс net.Listener,
    который используется для прослушивания входящих подключений
  • структуру net.Dialer,
    которая управляет параметрами установки соединения
  • тип net.TCPConn,
    который реализует интерфейс net.Conn для TCP-соединений
  • тип net.UDPConn,
    который реализует интерфейс net.Conn для UDP-соединений