C:/screenshot/配下にスクリーンショットが作成されたら、FTPで転送したいです。
androidとnavitageがDBで紐付けられていて、変換しています。
DB変換テーブルイメージ
android navitage
1 172
2 250
265 265
1回目は転送されるのですが、2回目になると半分ほどの容量だけ転送されていたりします。
エラー内容
2020/08/25 16:41:29 [INFO] スクリーンショット「C:\screenshot\265\20200806.png」転送完了
2020/08/25 16:41:53 [ERROR] 426 Failure reading network stream.
どうしても自分で解決できないので、なにか分かったら教えていただきたいです。
宜しくお願いします。
GO
1package main 2 3import ( 4 "crypto/tls" 5 "database/sql" 6 "io" 7 "os" 8 "strings" 9 10 _ "github.com/go-sql-driver/mysql" 11 "github.com/jlaffaye/ftp" 12 rotatelogs "github.com/lestrrat-go/file-rotatelogs" 13 "github.com/rjeczalik/notify" 14 "github.com/spiegel-im-spiegel/logf" 15) 16 17func main() { 18 19 // ************************************** 20 // ログファイル作成 21 // ************************************** 22 23 logf.SetMinLevel(logf.DEBUG) 24 rl, err := rotatelogs.New("log/tnvTCP_%Y%m%d.log") 25 if err != nil { 26 logf.Error(err) 27 return 28 } 29 ws := io.MultiWriter( 30 rl, 31 os.Stdout, 32 ) 33 34 logf.SetOutput(ws) 35 36 // ************************************** 37 // FTPS接続 38 // ************************************** 39 40 ftps, err := ftp.Dial("ftp.example.org:21", ftp.DialWithExplicitTLS(&tls.Config{ 41 // Set InsecureSkipVerify to skip the default validation we are 42 // replacing. This will not disable VerifyPeerCertificate. 43 InsecureSkipVerify: true, 44 45 // While packages like net/http will implicitly set ServerName, the 46 // VerifyPeerCertificate callback can't access that value, so it has to be set 47 // explicitly here or in VerifyPeerCertificate on the client side. If in 48 // an http.Transport DialTLS callback, this can be obtained by passing 49 // the addr argument to net.SplitHostPort. 50 ServerName: "www.navitage.net", 51 52 // On the server side, set ClientAuth to require client certificates (or 53 // VerifyPeerCertificate will run anyway and panic accessing certs[0]) 54 // but not verify them with the default verifier. 55 // ClientAuth: tls.RequireAnyClientCert, 56 })) 57 if err != nil { 58 logf.Error(err) 59 } 60 61 err = ftps.Login("anonymous", "anonymous") 62 if err != nil { 63 logf.Error(err) 64 } 65 defer ftps.Quit() 66 67 for { 68 69 // ************************************** 70 // データベース接続 71 // ************************************** 72 73 db, err := sql.Open("mysql", "root:pass@tcp(127.0.0.1:3306)/sample_db") 74 if err != nil { 75 logf.Error(err) 76 } 77 78 // ************************************** 79 // ファイル監視 80 // ************************************** 81 82 // Make the channel buffered to ensure no event is dropped. Notify will drop 83 // an event if the receiver is not able to keep up the sending pace. 84 c := make(chan notify.EventInfo, 1) 85 86 // Set up a watchpoint listening for events within a directory tree rooted 87 // at current working directory. Dispatch remove events to c. 88 if err := notify.Watch("C:/screenshot/...", c, notify.Create); err != nil { 89 logf.Error(err) 90 } 91 // defer notify.Stop(c) 92 93 event := <-c 94 95 notify.Stop(c) 96 97 filename := string(event.Path()) 98 99 var r *os.File 100 if r, err = os.Open(filename); err != nil { 101 logf.Error(err) 102 } 103 104 // ************************************** 105 // ファイル処理 106 // ************************************** 107 108 var arr []string 109 arr = strings.Split(filename, "\") 110 111 var navitage string 112 err = db.QueryRow("SELECT navitage FROM clientid WHERE android =?", arr[2]).Scan(&navitage) 113 if err != nil { 114 logf.Error(err) 115 // continue 116 } 117 ftps.ChangeDir("screenshot/" + navitage) 118 119 ch := make(chan string) 120 121 // for range time.Tick(60 * time.Second) { 122 123 go ftpsStor(ftps, arr, c, filename, ch, r) 124 125 cf := <-ch 126 close(ch) 127 128 if cf == "1" { 129 130 logf.Printf("スクリーンショット「" + event.Path() + "」転送完了") 131 132 r.Close() 133 err = os.Remove(filename) 134 if err != nil { 135 logf.Error(err) 136 } 137 } 138 db.Close() 139 } 140} 141 142// func ftpsStor(ftps *ftp.ServerConn, arr []string, db *sql.DB, filename string, event notify.EventInfo, r *os.File, ch chan string) { 143func ftpsStor(ftps *ftp.ServerConn, arr []string, c chan notify.EventInfo, filename string, ch chan string, r *os.File) { 144 145 if err := ftps.Stor(arr[3], r); err != nil { 146 logf.Error(err) 147 ch <- "0" 148 } else { 149 ch <- "1" 150 } 151} 152
参考にしたサイト
FTP
https://github.com/jlaffaye/ftp/blob/master/ftp.go
TLS
https://golang.org/pkg/crypto/tls/#example_Dial
GoでMySQLを利用する
https://noumenon-th.net/programming/2019/09/20/go-sql-driver/
Go初心者が、GolangとMySQLを接続してAPIを作ってみた
https://qiita.com/k_yoshikawa/items/e5d35d1252bbf0040bc3
Channels
https://tour.golang.org/concurrency/2
for
https://budougumi0617.github.io/2018/11/18/loop-by-time-tick-in-golang/
io.Reader
https://christina04.hatenablog.com/entry/2017/01/06/190000
https://www.yunabe.jp/docs/golang_io.html
channel待機
https://hori-ryota.com/blog/golang-channel-pattern/
ディレクトリ中のファイル一覧を取得する
https://ashitani.jp/golangtips/tips_dir.html#dir_GetFileList
ioutil.ReadDir 関数
https://waman.hatenablog.com/entry/2017/10/05/132727
ファイル監視(再帰的)
https://godoc.org/github.com/rjeczalik/notify#example-Watch--Recursive
あなたの回答
tips
プレビュー