FTP (ファイル転送プロトコル) は、サーバーとクライアントの間でファイルをアップロードおよびダウンロードするために使用できる一般的なファイル転送プロトコルです。 Go 言語は、高い効率と同時実行パフォーマンスを備えたオープンソース プログラミング言語です。この記事ではGo言語を使ってFTP機能を実装する方法を紹介します。
FTP プロトコルはクライアント/サーバー モデルに基づいており、クライアントはサーバーにリクエストを送信してファイルをアップロードまたはダウンロードします。 FTP クライアント プログラムは、TCP プロトコルを使用して FTP サーバーと通信し、FTP サーバーはポート 21 で待機します。FTP クライアントは、FTP サーバーとのデータ通信に異なるポート番号を使用します。 FTP プロトコルは、ファイル共有、Web サイトのファイル管理、バックアップなどのシナリオで一般的に使用されます。
FTP サーバーはポート 21 をリッスンし、クライアントから送信された FTP コマンドを解析する必要があります。通常、FTP クライアントは認証のためにユーザー名とパスワードを FTP サーバーに送信します。認証が成功すると、FTP クライアントはファイルのダウンロード、アップロード、ファイルの削除などのさまざまな FTP コマンドを実行できるようになります。
次に、FTP サーバーを実装するサンプル コードを示します。
package main import ( "fmt" "net" "os" "bufio" "strings" ) func main() { arguments := os.Args if len(arguments) == 1 { fmt.Println("Please provide a port number") return } PORT := ":" + arguments[1] l, err := net.Listen("tcp4", PORT) if err != nil { fmt.Println(err) return } defer l.Close() fmt.Println("Listening on " + PORT) for { conn, err := l.Accept() if err != nil { fmt.Println(err) continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { fmt.Println("Received connection from " + conn.RemoteAddr().String()) conn.Write([]byte("220 Welcome to FTP Server ")) username := "" for { message, err := bufio.NewReader(conn).ReadString(' ') if err != nil && err.Error() == "EOF" { break } fmt.Print("Message Received:", string(message)) command := strings.TrimSpace(string(message)) parts := strings.Split(command, " ") if parts[0] == "USER" { username = parts[1] conn.Write([]byte("331 Password required for " + username + " ")) } else if parts[0] == "PASS" { password := parts[1] if username == "admin" && password == "password" { conn.Write([]byte("230 Logged on ")) } else { conn.Write([]byte("530 Authentication failed ")) } } else if parts[0] == "QUIT" { conn.Write([]byte("221 Goodbye ")) conn.Close() break } else { conn.Write([]byte("500 Command not implemented ")) } } }
この例では、標準ライブラリの net パッケージを使用して TCP サーバーを実装します。サーバーはポート番号をリッスンし、新しい接続を受信したときに処理するために handleConnection 関数を呼び出します。 handleConnection 関数は、まず「220 Welcome to FTP Server」メッセージをクライアントに送信します。次に、サーバーはクライアントがユーザー名とパスワードを送信するのを待ち、bufio パッケージの ReadString 関数を呼び出してクライアントから送信されたメッセージを読み取ります。受信したメッセージが「USER」で始まる場合は、ユーザー名を保存し、「331 Password required」メッセージをクライアントに送信し、クライアントがパスワードを入力するのを待ちます。受信したメッセージが「PASS」で始まる場合は、パスワードが正しいことを確認してください。検証が成功すると、ユーザーが正常にログインしたことを示す「230 Logged on」メッセージがクライアントに送信されます。パスワードの検証が失敗した場合、「530 認証に失敗しました」というメッセージがクライアントに送信されます。受信したメッセージが「QUIT」で始まる場合、「221 Goodbye」メッセージがクライアントに送信され、クライアントとの接続が切断されます。
FTP クライアントは、FTP サーバーと通信するためのコードを実装する必要があります。 FTP クライアントは通常、コマンド ラインまたは GUI インターフェイスを通じてユーザーと対話し、アップロード、ダウンロード、削除、名前変更などの機能を提供します。
以下は簡単な FTP クライアントの例です:
package main import ( "bufio" "fmt" "net" "os" "strings" ) func main() { arguments := os.Args if len(arguments) == 1 { fmt.Println("Please provide a host:port string") return } CONNECT := arguments[1] c, err := net.Dial("tcp4", CONNECT) if err != nil { fmt.Println(err) return } for { message, err := bufio.NewReader(c).ReadString(' ') if err != nil { fmt.Println(err) return } fmt.Print("Message Received:", string(message)) if strings.Contains(strings.ToLower(message), "goodbye") { return } fmt.Print(">> ") commandReader := bufio.NewReader(os.Stdin) command, _ := commandReader.ReadString(' ') fmt.Fprintf(c, command+" ") } }
この例では、FTP クライアントは標準ライブラリの net パッケージを使用して実装されています。クライアントはコマンド ライン インターフェイスを通じてユーザーと対話します。まず、クライアントはダイヤル機能を介して FTP サーバーに接続します。その後、クライアントは FTP サーバーからメッセージを継続的に受信し、コマンド ライン インターフェイスに出力します。次に、クライアントはユーザーがコマンドを入力するのを待ち、Fprintf 関数を通じてコマンドを FTP サーバーに送信します。その後、クライアントは FTP サーバーからの応答を待ち続けます。
FTP クライアントは、STOR コマンドを使用してファイルをアップロードし、RETR コマンドを使用してファイルをダウンロードできます。 STOR コマンドは FTP サーバーにファイルをアップロードし、RETR コマンドは FTP サーバーからファイルをダウンロードします。
次は、単純な FTP ファイルのアップロードとダウンロードの例です。
package main import ( "fmt" "io" "net" "os" ) func main() { arguments := os.Args if len(arguments) == 1 { fmt.Println("Please provide a host:port string") return } CONNECT := arguments[1] c, err := net.Dial("tcp4", CONNECT) if err != nil { fmt.Println(err) return } for { var input string fmt.Scanln(&input) if input == "STOP" { fmt.Println("Exiting FTP Client") return } if input == "RETR" { fmt.Fprintf(c, input+" ") handleFileDownload(c) } else if input == "STOR" { fmt.Fprintf(c, input+" ") handleFileUpload(c) } else { fmt.Fprintf(c, input+" ") handleServerResponse(c) } } } func handleFileDownload(conn net.Conn) { var filename string fmt.Scanln(&filename) file, err := os.Create(filename) if err != nil { fmt.Println(err) return } defer file.Close() data := make([]byte, 2048) for { n, err := conn.Read(data) if err != nil && err != io.EOF { fmt.Println(err) return } if n == 0 { fmt.Println("Download complete") return } _, err = file.Write(data[:n]) if err != nil { fmt.Println(err) return } } } func handleFileUpload(conn net.Conn) { var filename string fmt.Scanln(&filename) file, err := os.Open(filename) if err != nil { fmt.Println(err) return } defer file.Close() fileInfo, err := file.Stat() if err != nil { fmt.Println(err) return } fmt.Fprintf(conn, "%d ", fileInfo.Size()) data := make([]byte, 2048) for { n, err := file.Read(data) if err != nil && err != io.EOF { fmt.Println(err) return } if n == 0 { fmt.Println("Upload complete") return } _, err = conn.Write(data[:n]) if err != nil { fmt.Println(err) return } } } func handleServerResponse(conn net.Conn) { response := make([]byte, 2048) n, err := conn.Read(response) if err != nil { fmt.Println(err) return } fmt.Println(string(response[:n])) }
この例では、FTP クライアントは、ファイルをアップロードおよびダウンロードするために「STOR」および「RETR」コマンドを実装します。 handleFileUpload 関数は、ユーザーが入力したファイル名からファイルを開き、ファイル サイズを FTP サーバーに送信します。次に、この関数はファイルの内容をチャンクで読み取り、FTP サーバーに送信します。 handleFileDownload 関数は、FTP サーバーからデータを受信し、新しく作成されたファイルにそれを書き込みます。 handleServerResponse 関数は、FTP サーバーから応答を読み取り、コンソールに出力します。
以上がgolangはftp機能を実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。