通过网络的TCP连接传输目录的内容

I am currently learning Go and I am trying to send the contents of a directory to another machine over a plain tcp connection using Go's net package. It works fine with individual files and small folders, but I run into issues if the folder contains many subfolders and larger files. I am using the filepath.Walk function to traverse over all files in the given directory. For each file or directory I send, I also send a header that provides the receiver with file name, file size, isDir properties so I know for how long I need to read for when reading the content. The issue I am having is that after a while when reading the header, I am reading actual file content of the previous file even though I already read that file from the connection

Here is the writer side. I simply traverse over the directory.

func transferDir(session *Session, dir string) error {
  return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }

    header := Header{Name: info.Name(), Size: info.Size(), Path: path}

    if info.IsDir() {
        header.SetDirBit()
        session.WriteHeader(header)
        return nil // nothing more to write
    }

    // content is a file. write the file now byte by byte
    file, err := os.Open(path)
    inf, err := file.Stat()

    header.Size = inf.Size() // get the true size of the file

    session.WriteHeader(header)

    defer file.Close()

    if err != nil {
        return err
    }

    buf := make([]byte, BUF_SIZE)

    for {
        n, err := file.Read(buf)

        if err != nil {
            if err == io.EOF {
                session.Write(buf[:n])
                session.Flush()
                break
            } else {
                log.Println(err)
                return err
            }
        }

        session.Write(buf[:n])
        session.Flush()
    }

    return nil

})

And here is the reader part

func (c *Clone) readFile(h Header) error {
    file, err := os.Create(h.Path)
    defer file.Close()
    if err != nil {
        return err
    }

    var receivedByts int64
    fmt.Printf("Reading File: %s Size: %d
", h.Name, h.Size)
    for {
        if (h.Size - receivedByts) < BUF_SIZE {
            n, err := io.CopyN(file, c.sesh, (h.Size - receivedByts))
            fmt.Println("Written: %d err: %s
", n, err)
            break
        }

        n, err := io.CopyN(file, c.sesh, BUF_SIZE)
        fmt.Println("Written: %d err: %s
", n, err)
        receivedByts += BUF_SIZE
        fmt.Println("Bytes Read: ", receivedByts)
    }

    return nil
}

Now the weird part is that when I am looking at the print statements I see something like: Reading File: test.txt Size: 14024

Written 1024 nil

Bytes Read 1024

... This continues all the way to the break statement

And the total of the Bytes read equals the actual file size. Yet, the subsequent read for the header will return content from the test.txt file. Almost like there is still stuff in the buffer, but I think I read it already....