@lucifer-m
golang php js html css

Как переиспользовать net.Connect?

После первой отправки данных соединение закрывается.
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")
}

Если убрать w.Flush() то соединение не закроется но и данные не отправятся. (я хочу в первой рутине заюзать n количество tcp.Send()
  • Вопрос задан
  • 606 просмотров
Решения вопроса 1
@lucifer-m Автор вопроса
golang php js html css
Я так и не понял почему заработало....
сервер
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
		}
	}

}

клиент
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
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@FireGM
Потому что tcp.Close() закрывает соединение.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы