Help!!! conn.Read() . Первый раз пишу TCP клиент-сервер и не могу понять проблему.

55 views
Skip to first unread message

Marko First

unread,
Jul 15, 2017, 11:05:21 AM7/15/17
to Golang Russian

После первой же итерации виснет, ввожу команды ничего не происходит, хотя стоит Scanf, вырубаю через диспетчер задач, появляется ошибка, а все что я писал идет просто в новой строке терминала. 


Помогите, 2 день не могу понять в чем проблема

package main

// CLIENT

import (
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "net"
    "os"
    "strings"
)

func main() {
    conn, err := net.Dial("tcp", "Localhost:3000")
    if err != nil {
        log.Fatalln(err)
    }
    pac := "C:/"
    forWrite(pac, err, conn)
}

func forWrite(pac string, err error, conn net.Conn) {
    _, err = conn.Write([]byte(pac)) //Передача
    if err != nil {
        log.Fatalln(err)
    }

    buffer := make([]byte, 1400)
    for { //Приём
        dataSize, err := conn.Read(buffer)
        data := buffer[:dataSize]
        fmt.Println(string(data))
        if err != nil {
            if err != io.EOF {
                log.Printf("Read error: %s", err)
            }
            break
        }
    }
    forNext(pac, err, conn)
}

func forNext(pac string, err error, conn net.Conn) {
    text := ""
    fmt.Scanf(text)
    arrayCommands := strings.Split(text, "|")

    switch arrayCommands[0] {
    case "goto":
        pac = pac + arrayCommands[1]
        forWrite(pac, err, conn)
    case "upload":
        upload(arrayCommands[1], arrayCommands[2], conn)
    case "delete":
        conn.Write([]byte(text))
    }
}

func upload(fileName string, directory string, conn net.Conn) {
    var currentByte int64 = 0
    fileBuffer := make([]byte, 1024)

    files, err := ioutil.ReadDir(directory)
    if err != nil {
        fmt.Println("closed")
        return
    }

    for _, f := range files {
        if f.Name() == fileName {
            file, err := os.Open(strings.TrimSpace(fileName))
            if err != nil {
                log.Fatal(err)
            }
            var err1 error

            for {
                _, err1 = file.ReadAt(fileBuffer, currentByte)
                currentByte += 1024
                if err1 == io.EOF {
                    break
                }

                forSend := []byte("upload" + fileName + "|" + string(fileBuffer))
                conn.Write(forSend)
            }
            file.Close()
            return
        }
    }
}



package main



// SERVER

import (

    "fmt"

    "io"

    "io/ioutil"

    "log"

    "net"

    "os"

    "strings"

)

func main() {
    listener, _ := net.Listen("tcp", "localhost:3000")
    fmt.Println("Start server")

    defer listener.Close()

    conn, err := listener.Accept()
    if err != nil {
        log.Fatalln(err)
    }

    fmt.Println("new connection")
    listenConnection(conn)
}



func listenConnection(conn net.Conn) {

    for {
        buffer := make([]byte, 1024)
        dataSize, err := conn.Read(buffer)
        if err != nil {
            fmt.Println("connection closed")
            return
        }
        data := buffer[:dataSize]

        if string(buffer[:3]) == "get" {
            sendFile(string(buffer[4:dataSize]), conn)
        } else if string(buffer[:6]) == "upload" {
            arrayText := strings.Split(string(buffer[6:dataSize]), "|")
            os.Create(arrayText[0])
            ioutil.WriteFile(arrayText[0], []byte(arrayText[1]), 0644)
        } else if string(buffer[:6]) == "delete" {
            os.Remove(string(buffer[7:dataSize]))
        } else {
            files, err := ioutil.ReadDir(string(data))
            if err != nil {
                fmt.Println("closed")
                break
            }
            for _, f := range files {
                fmt.Println(f.Name())
                conn.Write([]byte(f.Name()))
            }
        }
    }
}

func sendFile(fileName string, conn net.Conn) {
    var currentByte int64 = 0
    fileBuffer := make([]byte, 1024)
    file, err := os.Open(strings.TrimSpace(fileName))
    if err != nil {
        log.Fatal(err)
    }
    var err1 error
    for {
        _, err1 = file.ReadAt(fileBuffer, currentByte)
        currentByte += 1024
        fmt.Println(fileBuffer) // для проверки
        conn.Write(fileBuffer)
        if err1 == io.EOF {
            break
        }
    }
    file.Close()
    return
}





Сразу скажу, что я начинаю только понимать, что к чему и учусь, по этому не судите строго. Благодарю.

Oleg Bulatov

unread,
Jul 15, 2017, 3:17:07 PM7/15/17
to Golang Russian
fmt.Scanf(text) - этот вызов ничего не будет делать. Scanf иначе работает.
Нужно что-то подобное:

reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter command: ")
text, err := reader.ReadString('\n')
if err != nil {
    log.Fatal(err)
Reply all
Reply to author
Forward
0 new messages