func (h ReadHandlerFunc) ServeTFTP(w ReadRequest) {
	h(w)
}
ServeTFTP calls the ReadHandlerFunc function.
package tftp  
import (
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"path/filepath"
)
type ReadHandler interface {
	ServeTFTP(ReadRequest)
}
type WriteHandler interface {
	ReceiveTFTP(WriteRequest)
}
type ReadWriteHandler interface {
	ReadHandler
	WriteHandler
}
type WriteRequest interface {
	Addr() *net.UDPAddr
	Name() string
	Read([]byte) (int, error)
	Size() (int64, error)
	WriteError(ErrorCode, string)
	TransferMode() TransferMode
}
type writeRequest struct {
	conn *conn
	name string
}
func (w *writeRequest) Addr() *net.UDPAddr {
	return w.conn.remoteAddr.(*net.UDPAddr)
}
func (w *writeRequest) Name() string {
	return w.name
}
func (w *writeRequest) Read(p []byte) (int, error) {
	return w.conn.Read(p)
}
func (w *writeRequest) Size() (int64, error) {
	if w.conn.tsize == nil {
		return 0, ErrSizeNotReceived
	}
	return *w.conn.tsize, nil
}
func (w *writeRequest) WriteError(c ErrorCode, s string) {
	w.conn.sendError(c, s)
}
func (w *writeRequest) TransferMode() TransferMode {
	return w.conn.mode
}
type ReadRequest interface {
	Addr() *net.UDPAddr
	Name() string
	Write([]byte) (int, error)
	WriteError(ErrorCode, string)
	WriteSize(int64)
	TransferMode() TransferMode
}
type readRequest struct {
	conn *conn
	name string
}
func (w *readRequest) Addr() *net.UDPAddr {
	return w.conn.remoteAddr.(*net.UDPAddr)
}
func (w *readRequest) Name() string {
	return w.name
}
func (w *readRequest) Write(p []byte) (int, error) {
	return w.conn.Write(p)
}
func (w *readRequest) WriteError(c ErrorCode, s string) {
	w.conn.sendError(c, s)
}
func (w *readRequest) WriteSize(i int64) {
	w.conn.tsize = &i
}
func (w *readRequest) TransferMode() TransferMode {
	return w.conn.mode
}
func FileServer(dir string) ReadWriteHandler {
	return &fileServer{path: dir, log: newLogger("fileserver")}
}
type fileServer struct {
	log  *logger
	path string
}
func (f *fileServer) ServeTFTP(w ReadRequest) {
	path := filepath.Join(f.path, filepath.Clean(w.Name()))
	file, err := os.Open(path)
	if err != nil {
		log.Println(err)
		w.WriteError(ErrCodeFileNotFound, fmt.Sprintf("File %q does not exist", w.Name()))
		return
	}
	defer errorDefer(file.Close, f.log, "error closing file")
	finfo, _ := file.Stat()
	w.WriteSize(finfo.Size())
	if _, err = io.Copy(w, file); err != nil {
		log.Println(err)
	}
}
func (f *fileServer) ReceiveTFTP(r WriteRequest) {
	path := filepath.Join(f.path, filepath.Clean(r.Name()))
	file, err := os.Create(path)
	if err != nil {
		log.Println(err)
		r.WriteError(ErrCodeAccessViolation, fmt.Sprintf("Cannot create file %q", filepath.Clean(r.Name())))
	}
	defer errorDefer(file.Close, f.log, "error closing file")
	_, err = io.Copy(file, r)
	if err != nil {
		log.Println(err)
	}
}
type ReadHandlerFunc func(ReadRequest)