This is a creation in Article, where the information may have evolved or changed.
Package Mainimport ("Bufio" "bytes" "Flag" "FMT" "IO" "Log" "Net/http" "OS" "Path/filepath" "Strings" "GITHUB.COM/CZXICHEN/AUTOWORK/TOOLS/MD5" "Github.com/czxichen/autowork/tools/split") Var (raddr, LaddrstringSdir, Ddir, excludestringPassname []stringResultstring="result/") Func init () {flag. Stringvar (&ddir,"D","","-d specifies the directory to match") flag. Stringvar (&sdir,"S","","-s specifies the directory to read") flag. Stringvar (&RADDR,"P","","-p specifies the IP and port of the original directory") flag. Stringvar (&LADDR,"L",": 1789","-L 127.0.0.1:1789 Specifies the port to listen for") flag. Stringvar (&exclude,"V","","-V log,txt specifies the excluded suffix file") flag. Parse ()}func main () {ifSdir! =""&& laddr! =""{Server() return}ifDdir! =""&& raddr! =""{Client (RADDR) return} flag. Usage ()}funcServer() {sdir = filepath. Toslash (Sdir)if!strings. Hassuffix (Sdir,"/") {Sdir + ="/"}ifExclude! =""{Passname = strings.Split(Exclude,",")} OS. Mkdirall (Result,0666) Walk (sdir) http. Handlefunc ("/", Router) http. Listenandserve (laddr, nil)}func Router (w http. Responsewriter, R *http.Request) {Log. Printf ("Remote address:%s\t Access path:%s\n", R.remoteaddr, R.url. Path) defer r.body.close () switch r.url. Path { Case "/": File,Err: = OS. Open ("Md5_list.txt")if Err! = Nil {http. NotFound (W, R) return} IO. Copy (W, File) File.close () Case "/result": File,Err: = OS. Create (Result + strings).Split(R.REMOTEADDR,":")[0] +". txt")if Err! = Nil {http.Error(W,Err.Error(),501) return} io. Copy (file, r.body) file. Close () Case "/FLUSHMD5": Walk (Sdir) fmt. Fprintln (W,"Flush MD5 list OK")}}func Walk (dirstring) {File,Err: = OS. Create ("Md5_list.txt")if Err! = Nil {Log. Println ("Failed to create MD5 list file:",Err.Error()) return} defer File.close ()Err= FilePath. Walk (dir, func (Rootstring, Info OS. FileInfo,Err Error)Error{if Err! = Nil {returnErr}ifInfo. Isdir () {return nil}ifExclude (Root) {return nil} M5,Err: = MD5. MD5 (Root)if Err! = Nil {Log. Printf ("Read file:%s MD5 failed with error message: \ n", Root,Err.Error()) returnErr} root = Strings. Trimprefix (filepath. Toslash (Root), dir) fmt. Fprintln (File, Root, M5) return nil})if Err! = Nil {Log. Println ("Traversing folder error:",Err.Error()) }Log. Println ("Traverse get MD5 Complete")}func Exclude (Suffixstring) BOOL { for_, Name: = Range Passname {ifStrings. Hassuffix (Suffix, name) {returntrue}} returnfalse}func Client (IPstring) {Ddir = filepath. Toslash (Ddir)if!strings. Hassuffix (Ddir,"/") {Ddir + ="/"} resp,Err: = http.Get("http //"+ IP)if Err! = Nil {fmt. Println ("Connection remote error:",Err.Error()) return} buf: = bytes. Newbuffer (nil) io. Copy (buf, resp. Body) resp. Body.close () File,Err: = OS. Create ("Cmd5_list.txt")if Err! = Nil {fmt. Println ("failed to create result file:",Err.Error()) return} defer File.close ()Err= Compare (buf, File, Ddir)if Err! = Nil {fmt. Println (Err)} file.sync () File.seek (0,0)Err= Client (File, IP)if Err! = Nil {fmt. Println ("Error uploading Result:",Err.Error())} OS. Remove ("Cmd5_list.txt")}func Compare (R io. Reader, W io. Writer, DSTstring)Error{rd: = Bufio. Newreader (R) for{line, _,Err: = Rd. ReadLine ()if Err! = Nil {if Err= = Io. EOF {Break} returnErr} PATH_MD5: =Split.Split(string(line))if Len(PATH_MD5)! =2{Continue} M5,Err: = MD5. MD5 (DST + path_md5[0])if Err! = Nil {ifOs. Isnotexist (Err) {FMT. Fprintln (W, path_md5[0], path_md5[1],"' File_not_is_exist '") }Else{FMT. Fprintln (W, path_md5[0], path_md5[1],Err.Error())} Continue}ifpath_md5[1]! = M5 {fmt. Fprintln (W, path_md5[0], path_md5[1], M5)}} return Nil}func client (R io. Reader, IPstring)Error{RESP,Err: = http. Post ("http //"+ip+"/result","Application/octet-stream", R)if Err! = Nil {returnErr} resp. Body.close () return nil}