func handleGet(filename string, address string) error { serverAddr, conn, err := getAddrAndConn(address) if err != nil { return err } defer conn.Close() rrq := common.RequestPacket{ OpCode: common.OpRRQ, Filename: filename, Mode: "octet", } _, err = conn.WriteTo(rrq.ToBytes(), serverAddr) if err != nil { return fmt.Errorf("Error sending RRQ packet: %v", err) } f, err := os.Create(filename) if err != nil { return fmt.Errorf("Error creating file: %v", err) } defer f.Close() bw := bufio.NewWriter(f) defer bw.Flush() var n int tid := uint16(1) packet := make([]byte, common.MaxPacketSize) for { // Always use the serverAddr returned as it changes after the first packet. n, serverAddr, err = common.WriteFile(bw, conn, serverAddr, packet, tid) if err != nil { return err } if n < 4+common.BlockSize { break } tid++ } return nil }
// handle reading a local file and sending it to the server func handlePut(filename, address string) error { f, err := os.Open(filename) if err != nil { return fmt.Errorf("Error opening file: %v", err) } defer f.Close() br := bufio.NewReader(f) serverAddr, conn, err := getAddrAndConn(address) if err != nil { return err } defer conn.Close() // Send WRQ packet wrq := common.RequestPacket{ OpCode: common.OpWRQ, Filename: filename, Mode: "octet", } _, err = conn.WriteTo(wrq.ToBytes(), serverAddr) if err != nil { return fmt.Errorf("Error sending WRQ packet: %v", err) } // Get the ACK ackBuf := make([]byte, 4) _, remoteAddr, err := conn.ReadFrom(ackBuf) if err != nil { return fmt.Errorf("Error reading ACK packet: %v", err) } _, err = common.ParseAckPacket(ackBuf) if err != nil { return fmt.Errorf("Error parsing ACK packet: %v", err) } common.ReadFileLoop(br, conn, remoteAddr, common.BlockSize) return nil }