From df622467dd1ed317779bec9a982eaa8b28215b0c Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Tue, 17 Oct 2017 18:43:12 -0600 Subject: [PATCH] Rewrite --- client.go | 91 ----------------------- test/connect.go => connect.go | 0 main.go | 66 +++++++---------- test/relay.go => relay.go | 0 rendevouz.go | 97 ------------------------ server.go | 134 ---------------------------------- test/main.go | 59 --------------- 7 files changed, 26 insertions(+), 421 deletions(-) delete mode 100644 client.go rename test/connect.go => connect.go (100%) rename test/relay.go => relay.go (100%) delete mode 100644 rendevouz.go delete mode 100644 server.go delete mode 100644 test/main.go diff --git a/client.go b/client.go deleted file mode 100644 index 5bf3620..0000000 --- a/client.go +++ /dev/null @@ -1,91 +0,0 @@ -package main - -import ( - "fmt" - "io" - "net" - "os" - "os/exec" - "strconv" - "strings" - "sync" - "time" - - "github.com/gosuri/uiprogress" - log "github.com/sirupsen/logrus" -) - -func runClient() { - uiprogress.Start() - var wg sync.WaitGroup - wg.Add(numberConnections) - bars := make([]*uiprogress.Bar, numberConnections) - for id := 0; id < numberConnections; id++ { - go func(id int) { - defer wg.Done() - port := strconv.Itoa(27001 + id) - connection, err := net.Dial("tcp", "localhost:"+port) - if err != nil { - panic(err) - } - defer connection.Close() - - bufferFileName := make([]byte, 64) - bufferFileSize := make([]byte, 10) - - connection.Read(bufferFileSize) - fileSize, _ := strconv.ParseInt(strings.Trim(string(bufferFileSize), ":"), 10, 64) - bars[id] = uiprogress.AddBar(int(fileSize+1028) / 1024).AppendCompleted().PrependElapsed() - - connection.Read(bufferFileName) - fileName = strings.Trim(string(bufferFileName), ":") - os.Remove(fileName + "." + strconv.Itoa(id)) - newFile, err := os.Create(fileName + "." + strconv.Itoa(id)) - if err != nil { - panic(err) - } - defer newFile.Close() - - var receivedBytes int64 - for { - if (fileSize - receivedBytes) < BUFFERSIZE { - io.CopyN(newFile, connection, (fileSize - receivedBytes)) - // Empty the remaining bytes that we don't need from the network buffer - connection.Read(make([]byte, (receivedBytes+BUFFERSIZE)-fileSize)) - break - } - io.CopyN(newFile, connection, BUFFERSIZE) - //Increment the counter - receivedBytes += BUFFERSIZE - bars[id].Incr() - } - }(id) - } - wg.Wait() - - // cat the file - os.Remove(fileName) - finished, err := os.Create(fileName) - defer finished.Close() - if err != nil { - log.Fatal(err) - } - for id := 0; id < numberConnections; id++ { - fh, err := os.Open(fileName + "." + strconv.Itoa(id)) - if err != nil { - log.Fatal(err) - } - - _, err = io.Copy(finished, fh) - if err != nil { - log.Fatal(err) - } - fh.Close() - os.Remove(fileName + "." + strconv.Itoa(id)) - } - cmd := exec.Command("cmd", "/c", "cls") - cmd.Stdout = os.Stdout - cmd.Run() - fmt.Println("\n\n\nDownloaded " + fileName + "!") - time.Sleep(1 * time.Second) -} diff --git a/test/connect.go b/connect.go similarity index 100% rename from test/connect.go rename to connect.go diff --git a/main.go b/main.go index b26f7d7..807a39e 100644 --- a/main.go +++ b/main.go @@ -3,22 +3,28 @@ package main import ( "flag" "fmt" + "os" log "github.com/sirupsen/logrus" ) const BUFFERSIZE = 1024 -const numberConnections = 8 +const numberConnections = 4 // Build flags var server, file string // Global varaibles -var serverAddress, fileName string +var serverAddress, fileName, codePhraseFlag, connectionTypeFlag string +var runAsRelay, debugFlag bool func main() { + flag.BoolVar(&runAsRelay, "relay", false, "run as relay") + flag.BoolVar(&debugFlag, "debug", false, "debug mode") flag.StringVar(&serverAddress, "server", "", "(run as client) server address to connect to") flag.StringVar(&fileName, "file", "", "(run as server) file to serve") + flag.StringVar(&codePhraseFlag, "code", "", "(run as server) file to serve") + flag.StringVar(&connectionTypeFlag, "type", "", "(run as server) file to serve") flag.Parse() // Check build flags too, which take precedent if server != "" { @@ -27,47 +33,27 @@ func main() { if file != "" { fileName = file } - fmt.Println(` - * ,MMM8&&&. * - MMMM88&&&&& . - MMMM88&&&&&&& - * MMM88&&&&&&&& - MMM88&&&&&&&& - 'MMM88&&&&&&' - 'MMM8&&&' * - |\___/| - ) ( . ' - =\ /= - )===( * - / \ - | | - / \ - \ / - _/\_/\_/\__ _/_/\_/\_/\_/\_/\_/\_/\_/\_/\_ - | | | |( ( | | | | | | | | | | - | | | | ) ) | | | | | | | | | | - | | | |(_( | | | | | | | | | | - | | | | | | | | | | | | | | | - | | | | | | | | | | | | | | | -`) - if len(fileName) != 0 { + + if len(fileName) > 0 { + _, err := os.Open(fileName) + if err != nil { + log.Fatal(err) + return + } + } + + log.SetFormatter(&log.TextFormatter{}) + if debugFlag { + log.SetLevel(log.DebugLevel) + } else { + log.SetLevel(log.WarnLevel) + } + + if runAsRelay { runServer() } else if len(serverAddress) != 0 { - runClient() + runClient(connectionTypeFlag, codePhraseFlag) } else { fmt.Println("You must specify either -file (for running as a server) or -server (for running as a client)") } } - -func init() { - // Log as JSON instead of the default ASCII formatter. - // log.SetFormatter(&log.JSONFormatter{}) - log.SetFormatter(&log.TextFormatter{}) - - // Output to stdout instead of the default stderr - // Can be any io.Writer, see below for File example - // log.SetOutput(os.Stdout) - - // Only log the warning severity or above. - log.SetLevel(log.DebugLevel) -} diff --git a/test/relay.go b/relay.go similarity index 100% rename from test/relay.go rename to relay.go diff --git a/rendevouz.go b/rendevouz.go deleted file mode 100644 index 0ba0621..0000000 --- a/rendevouz.go +++ /dev/null @@ -1,97 +0,0 @@ -package main - -import ( - "net" -) - -// also see : http://archive.is/4Um4u - -// func runRendevouz() { -// // Listen on the specified TCP port on all interfaces. -// from := "0.0.0.0:27001" -// to := "0.0.0.0:27009" -// l, err := net.Listen("tcp", to) -// if err != nil { -// log.Fatal(err) -// } -// defer l.Close() -// for { -// // Wait for a connection. -// c, err := l.Accept() -// if err != nil { -// log.Fatal(err) -// } - -// // handle the connection in a goroutine -// go wormhole(c, from) -// } -// } - -// func relay(c net.Conn, from string) { -// defer c.Close() -// log.Println("Opening relay to", c.RemoteAddr()) - -// // connect to the destination tcp port -// destConn, err := net.Dial("tcp", *to) -// if err != nil { -// log.Fatal("Error connecting to destination port") -// } -// defer destConn.Close() -// log.Println("Wormhole open from", c.RemoteAddr()) - -// go func() { io.Copy(c, destConn) }() -// io.Copy(destConn, c) - -// log.Println("Stopping wormhole from", c.RemoteAddr()) -// } - -// BETTER? - -// chanFromConn creates a channel from a Conn object, and sends everything it -// Read()s from the socket to the channel. -func chanFromConn(conn net.Conn) chan []byte { - c := make(chan []byte) - - go func() { - b := make([]byte, 1024) - - for { - n, err := conn.Read(b) - if n > 0 { - res := make([]byte, n) - // Copy the buffer so it doesn't get changed while read by the recipient. - copy(res, b[:n]) - c <- res - } - if err != nil { - c <- nil - break - } - } - }() - - return c -} - -// Pipe creates a full-duplex pipe between the two sockets and transfers data from one to the other. -func Pipe(conn1 net.Conn, conn2 net.Conn) { - chan1 := chanFromConn(conn1) - chan2 := chanFromConn(conn2) - - for { - select { - case b1 := <-chan1: - if b1 == nil { - return - } else { - conn2.Write(b1) - } - case b2 := <-chan2: - if b2 == nil { - return - } else { - conn1.Write(b2) - } - } - } -} diff --git a/server.go b/server.go deleted file mode 100644 index 45cb4ab..0000000 --- a/server.go +++ /dev/null @@ -1,134 +0,0 @@ -package main - -import ( - "fmt" - "io" - "math" - "net" - "os" - "strconv" - "sync" - - "github.com/pkg/errors" - log "github.com/sirupsen/logrus" -) - -func runServer() { - logger := log.WithFields(log.Fields{ - "function": "main", - }) - logger.Info("Initializing") - var wg sync.WaitGroup - wg.Add(numberConnections) - for id := 0; id < numberConnections; id++ { - go listenerThread(id, &wg) - } - wg.Wait() -} - -func listenerThread(id int, wg *sync.WaitGroup) { - logger := log.WithFields(log.Fields{ - "function": "listenerThread@" + serverAddress + ":" + strconv.Itoa(27000+id), - }) - - defer wg.Done() - - err := listener(id) - if err != nil { - logger.Error(err) - } -} - -func listener(id int) (err error) { - port := strconv.Itoa(27001 + id) - logger := log.WithFields(log.Fields{ - "function": "listener@" + serverAddress + ":" + port, - }) - server, err := net.Listen("tcp", serverAddress+":"+port) - if err != nil { - return errors.Wrap(err, "Error listening on "+serverAddress+":"+port) - } - defer server.Close() - logger.Info("waiting for connections") - //Spawn a new goroutine whenever a client connects - for { - connection, err := server.Accept() - if err != nil { - return errors.Wrap(err, "problem accepting connection") - } - logger.Infof("Client %s connected", connection.RemoteAddr().String()) - go sendFileToClient(id, connection) - } -} - -//This function is to 'fill' -func fillString(retunString string, toLength int) string { - for { - lengthString := len(retunString) - if lengthString < toLength { - retunString = retunString + ":" - continue - } - break - } - return retunString -} - -func sendFileToClient(id int, connection net.Conn) { - logger := log.WithFields(log.Fields{ - "function": "sendFileToClient #" + strconv.Itoa(id), - }) - defer connection.Close() - //Open the file that needs to be send to the client - file, err := os.Open(fileName) - if err != nil { - fmt.Println(err) - return - } - defer file.Close() - //Get the filename and filesize - fileInfo, err := file.Stat() - if err != nil { - fmt.Println(err) - return - } - - numChunks := math.Ceil(float64(fileInfo.Size()) / float64(BUFFERSIZE)) - chunksPerWorker := int(math.Ceil(numChunks / float64(numberConnections))) - - bytesPerConnection := int64(chunksPerWorker * BUFFERSIZE) - if id+1 == numberConnections { - bytesPerConnection = fileInfo.Size() - (numberConnections-1)*bytesPerConnection - } - fileSize := fillString(strconv.FormatInt(int64(bytesPerConnection), 10), 10) - - fileName := fillString(fileInfo.Name(), 64) - - if id == 0 || id == numberConnections-1 { - logger.Infof("numChunks: %v", numChunks) - logger.Infof("chunksPerWorker: %v", chunksPerWorker) - logger.Infof("bytesPerConnection: %v", bytesPerConnection) - logger.Infof("fileName: %v", fileInfo.Name()) - } - - logger.Info("sending") - connection.Write([]byte(fileSize)) - connection.Write([]byte(fileName)) - sendBuffer := make([]byte, BUFFERSIZE) - - chunkI := 0 - for { - _, err = file.Read(sendBuffer) - if err == io.EOF { - //End of file reached, break out of for loop - logger.Info("EOF") - break - } - if (chunkI >= chunksPerWorker*id && chunkI < chunksPerWorker*id+chunksPerWorker) || (id == numberConnections-1 && chunkI >= chunksPerWorker*id) { - connection.Write(sendBuffer) - } - chunkI++ - } - fmt.Println("File has been sent, closing connection!") - return -} diff --git a/test/main.go b/test/main.go deleted file mode 100644 index 807a39e..0000000 --- a/test/main.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - - log "github.com/sirupsen/logrus" -) - -const BUFFERSIZE = 1024 -const numberConnections = 4 - -// Build flags -var server, file string - -// Global varaibles -var serverAddress, fileName, codePhraseFlag, connectionTypeFlag string -var runAsRelay, debugFlag bool - -func main() { - flag.BoolVar(&runAsRelay, "relay", false, "run as relay") - flag.BoolVar(&debugFlag, "debug", false, "debug mode") - flag.StringVar(&serverAddress, "server", "", "(run as client) server address to connect to") - flag.StringVar(&fileName, "file", "", "(run as server) file to serve") - flag.StringVar(&codePhraseFlag, "code", "", "(run as server) file to serve") - flag.StringVar(&connectionTypeFlag, "type", "", "(run as server) file to serve") - flag.Parse() - // Check build flags too, which take precedent - if server != "" { - serverAddress = server - } - if file != "" { - fileName = file - } - - if len(fileName) > 0 { - _, err := os.Open(fileName) - if err != nil { - log.Fatal(err) - return - } - } - - log.SetFormatter(&log.TextFormatter{}) - if debugFlag { - log.SetLevel(log.DebugLevel) - } else { - log.SetLevel(log.WarnLevel) - } - - if runAsRelay { - runServer() - } else if len(serverAddress) != 0 { - runClient(connectionTypeFlag, codePhraseFlag) - } else { - fmt.Println("You must specify either -file (for running as a server) or -server (for running as a client)") - } -}