Go coordination tcp received data problem, multiple transmissions received in the same one

  golang, question

I wrote a tcp test for sending and receiving files, the code is as follows
Server side

package main
 
 import (
 //"bytes"
 "fmt"
 "io"
 "math/rand"
 "net"
 "os"
 "time"
 )
 
 func checkError(err error) {
 if err !  = nil {
 fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
 os.Exit(1)
 }
 }
 
 func main() {
 ln, err := net.Listen("tcp", ":8080")
 checkError(err)
 
 for {
 conn, err := ln.Accept()
 if err !  = nil {
 fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
 continue
 }
 go run(conn)
 
 }
 }
 
 func run(conn net.Conn) {
 var all_len int = 0
 buffer := make([]byte, 20480)
 rand.Seed(time.Now().Unix())
 filename := string(rand.Intn(100))
 writeFile, err := os.OpenFile(filename, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)
 if err !  = nil {
 fmt.Println("create file error:", filename, err)
 return
 }
 defer writeFile.Close()
 for {
 
 lenght, err := conn.Read(buffer)
 if err !  = nil {
 if err == io.EOF {
 break
 }
 fmt.Fprintf(os.Stderr, "read buff error: %s", err.Error())
 return
 }
 fmt.Println("receive data lenght:", lenght)
 
 //_, err = writeFile.Write(buffer[:bytes.Index(buffer[:], []byte{0})])
 _, err = writeFile.Write(buffer[:lenght])
 if err !  = nil {
 fmt.Println("write file error", err)
 return
 }
 
 all_len += lenght
 
 }
 fmt.Println("write file done", all_len/1024/1024)
 return
 }

Client side

package main
 
 import (
 //"bytes"
 "fmt"
 "io"
 "net"
 "os"
 //"time"
 )
 
 func checkError(err error) {
 if err !  = nil {
 fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
 os.Exit(1)
 }
 }
 
 func main() {
 ch := make(chan int)
 for i := 0;   i < 3;  i++ {
 go send(ch)
 }
 for w := range ch {
 fmt.Println(w)
 }
 }
 
 func send(ch chan int) {
 
 conn, err := net.Dial("tcp", "127.0.0.1:8080")
 checkError(err)
 fileHandle, err := os.Open("Visio2010_cn.exe")
 if err !  = nil {
 fmt.Println("open file ERROR", err)
 return
 }
 defer fileHandle.Close()
 io.Copy(conn, fileHandle)
 conn.Close()
 ch <- 1
 }

Question:
1. What I mean is that I want to send 3 files at the same time (the same file is sent, this is not important). The important thing is that only one file is generated when I accept it. This file is 3 times the size of the file sent. The received data is written in the same file. Why is this so?

2. Why are the packets not equal in size, big or small, as shown in the figure, is this the reason for subcontracting?

3. I haven’t written anything about tcp before. Please give me your advice if you have any code problems.

请输入图片描述

The key problem should be here:

rand.Seed(time.Now().Unix())
 filename := string(rand.Intn(100))

Because callinggoThe last three goroutine may have been executed before the file was created, and then the generated random numbers are consistent, resulting in the same file.

One solution is to generate random numbers outside and pass the file name to goroutine. Also, in a program,rand.Seed(time.Now().Unix())Only one initialization is required.