V
V
Vladimir Grabko2016-05-14 18:48:47
go
Vladimir Grabko, 2016-05-14 18:48:47

How to reuse net.Connect?

After the first data is sent, the connection is closed.
main.go

package main

import (
  "fmt"
  "luciferKernel/net/tcp/client"
  "luciferKernel/net/tcp/server"
  "time"
)

func main() {
  go func() {
    time.Sleep(1000 * time.Millisecond)
    tcp, _ := client.Connect("localhost", "3333")
    data, err := tcp.Send("ConnectionClose")
    if err == nil {
      fmt.Println("Получил:", data)
    }

    tcp.Close()
  }()

  server.Run("localhost", "3333", func(data string) string {
    fmt.Println("Получил:", data)
    return "test"
  })
}

client
package client

import (
  "bufio"
  "fmt"
  "io"
  "net"
  "strings"
)

type TcpClient struct {
  r    *bufio.Reader
  w    *bufio.Writer
  buf  []byte
  conn net.Conn
}

func Connect(host string, port string) (TcpClient, error) {
  fmt.Println("Connect")
  conn, err := net.Dial("tcp", host+":"+port)
  return TcpClient{
    buf:  make([]byte, 1024),
    r:    bufio.NewReader(conn),
    w:    bufio.NewWriter(conn),
    conn: conn,
  }, err
}

func (tcp TcpClient) Send(dataSend string) (string, error) {
  tcp.w.WriteString(dataSend + "\r\n\r\n")
  tcp.w.Flush()
  var (
    returnData string
    returnErr  error
  )
ILOOP:
  for {
    n, err := tcp.r.Read(tcp.buf)
    data := string(tcp.buf[:n])
    switch err {
    case io.EOF:
      break ILOOP
    case nil:
      returnData = data
      returnErr = nil
      if isTransportOver(data) {
        break ILOOP
      }
    default:
      returnData = ""
      returnErr = err
    }
  }
  return returnData, returnErr
}
func (tcp TcpClient) Close() {
  tcp.conn.Close()
}

func isTransportOver(data string) (over bool) {
  over = strings.HasSuffix(data, "\r\n\r\n")
  return
}

server
package server

import (
  "bufio"
  "fmt"
  "io"
  "net"
  "os"
  "strings"
)

func Run(host string, port string, handle func(data string) string) {
  l, err := net.Listen("tcp", host+":"+port)
  if err != nil {
    fmt.Println("Error listening:", err.Error())
    os.Exit(1)
  }
  defer l.Close()
  fmt.Println("Слушает " + host + ":" + port)
  for {
    conn, err := l.Accept()
    if err != nil {
      fmt.Println("Ошибка запуска: ", err.Error())
      os.Exit(1)
    }
    go handleRequest(conn, handle)
  }
}

func handleRequest(conn net.Conn, handle func(data string) string) {
  fmt.Println("handleRequest")
  var (
    buf = make([]byte, 1024)
    r   = bufio.NewReader(conn)
    w   = bufio.NewWriter(conn)
  )
ILOOP:
  for {
    n, err := r.Read(buf)
    data := string(buf[:n])
    switch err {
    case io.EOF:
      break ILOOP
    case nil:

      if string(data) == "ConnectionClose" {
        conn.Close()
      } else {
        w.WriteString(handle(data) + "\r\n\r\n")
        w.Flush()
      }

      //log.Println(data)
      if isTransportOver(data) {
        break ILOOP
      }
    default:
      fmt.Println("Ошибка при получении:", err)
      return
    }
  }
  fmt.Println("Соединение закрыто")
  conn.Close()
}
func isTransportOver(data string) bool {
  return strings.HasSuffix(data, "\r\n\r\n")
}

If you remove w.Flush(), then the connection will not be closed, but the data will not be sent either. (I want to use n number of tcp.Send() in the first routine

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vladimir Grabko, 2016-05-14
@lucifer-m

I still do not understand why it worked ....
server

package server

import (
  "bufio"
  "fmt"
  "io"
  "net"
  "os"
)

func Run(host string, port string, handle func(data string) string) {
  l, err := net.Listen("tcp", host+":"+port)
  if err != nil {
    fmt.Println("Error listening:", err.Error())
    os.Exit(1)
  }
  defer l.Close()
  fmt.Println("Слушает " + host + ":" + port)
  for {
    conn, err := l.Accept()
    if err != nil {
      fmt.Println("Ошибка запуска: ", err.Error())
      os.Exit(1)
    }
    go handleRequest(conn, handle)
  }
}

func handleRequest(conn net.Conn, handle func(data string) string) {
  fmt.Println("handleRequest")
  var (
    buf = make([]byte, 1024)
    r   = bufio.NewReader(conn)
    w   = bufio.NewWriter(conn)
  )
ILOOP:
  for {
    n, err := r.Read(buf)
    data := string(buf[:n])
    switch err {
    case io.EOF:
      break ILOOP
    case nil:

      if string(data) == "ConnectionClose" {
        fmt.Println("Соединение закрыто")
        w.WriteString("ConnectionClose\r\n")
        w.Flush()
        conn.Close()
      } else {
        w.WriteString(handle(data) + "\r\n")
        w.Flush()
        //break ILOOP
      }

    default:
      fmt.Println("Ошибка при получении:", err)
      break ILOOP
    }
  }

}

customer
package client

import (
  "bufio"
  "fmt"
  "io"
  "net"
  "strings"
)

type TcpClient struct {
  r    *bufio.Reader
  w    *bufio.Writer
  buf  []byte
  conn net.Conn
}

func Connect(host string, port string) (TcpClient, error) {
  fmt.Println("Connect")
  conn, err := net.Dial("tcp", host+":"+port)
  return TcpClient{
    buf:  make([]byte, 1024),
    r:    bufio.NewReader(conn),
    w:    bufio.NewWriter(conn),
    conn: conn,
  }, err
}

func (tcp TcpClient) Send(dataSend string) (string, error) {
  var (
    returnData string
    returnErr  error
  )
  tcp.w.WriteString(dataSend + "\r\n")
  tcp.w.Flush()
ILOOP:
  for {
    n, err := tcp.r.Read(tcp.buf)
    data := string(tcp.buf[:n])
    switch err {
    case io.EOF:
      break ILOOP
    case nil:
      returnData = data
      returnErr = nil
      if isTransportOver(data) {
        break ILOOP
      }
    default:
      returnData = ""
      returnErr = err
    }
  }
  return returnData, returnErr
}
func (tcp TcpClient) Close() {
  tcp.conn.Close()
}

func isTransportOver(data string) (over bool) {
  over = strings.HasSuffix(data, "\r\n")
  return
}

I
Ilya, 2016-05-14
@FireGM

Because tcp.Close() closes the connection.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question