Created
June 21, 2023 10:33
-
-
Save kehiy/4bff455048a8bedf4f9374b8899b2f43 to your computer and use it in GitHub Desktop.
Stream large files over a TCP connection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"crypto/rand" | |
"encoding/binary" | |
"fmt" | |
"io" | |
"log" | |
"net" | |
"time" | |
) | |
type FileServer struct { } | |
func (fs *FileServer) start() { | |
ln, err := net.Listen("tcp", "0.0.0.0:3000") | |
if err != nil { | |
panic(err) | |
} | |
for { | |
conn, err := ln.Accept() | |
if err != nil { | |
log.Fatal(err) | |
continue | |
} | |
fmt.Printf("new connection: %s\n", conn.RemoteAddr().String()) | |
// read data from accepted connections | |
go fs.readLoop(conn) | |
} | |
} | |
func (fs *FileServer) readLoop(conn net.Conn) { | |
// make a new buffer | |
buf := new(bytes.Buffer) | |
for { | |
var size int64 | |
// get the size from connection | |
binary.Read(conn, binary.LittleEndian, &size) | |
// copy from connection until the end of file | |
n, err := io.CopyN(buf, conn, size) | |
if err != nil { | |
log.Fatal(err) | |
continue | |
} | |
fmt.Println(buf.Bytes()) | |
fmt.Printf("received %d bytes over the network\n", n) | |
} | |
} | |
func main() { | |
go func () { | |
time.Sleep(4 * time.Second) | |
// set your file szie | |
sendFile(2000000) | |
}() | |
s := &FileServer{} | |
s.start() | |
} | |
func sendFile(size int) error { | |
file := make([]byte, size) | |
// make a random file from the size provided | |
_, err := io.ReadFull(rand.Reader, file) | |
if err != nil { | |
return err | |
} | |
// dial with the tcp server (you can do this is an other file) | |
conn, err := net.Dial("tcp", ":3000") | |
if err != nil { | |
return err | |
} | |
// send the size of file | |
binary.Write(conn, binary.LittleEndian, int64(size)) | |
// copy file over the network until the end of file | |
n, err := io.CopyN(conn, bytes.NewReader(file), int64(size)) | |
if err != nil { | |
return err | |
} | |
fmt.Printf("written %d byte over the network\n", n) | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment