前言
Go网络编程的学习代码示例:网络文件传输。
代码仓库
概要
接续上一章“Go网络编程的学习代码示例:客户端/服务端(C/S)模型”内容,本章将传输的用户输入数据改为传输文件
注意:关于网络编程的代码,上一章有详细的注释,本章不再过多注释,只注释新增的网络文件传输相关内容
内容
- 使用服务端/客户端(C/S)模型
- 实现发送方(客户端)和接收方(服务端)的简单网络文件传输:发送方发送文件名,接收方回复响应,发送方再发送文件内容,接收方接收文件内容并保存在当前目录
网络传输文件的形式和本地传输文件类似,本质是写读文件
流程
发送方:客户端
- 接收用户输入,获取完整文件路径并提取文件信息:fmt.Scan()、os.Stat()
- 发送连接请求:net.Dial()
- 发送文件名:net.Write()
- 接收,接收方接收到文件名后的响应信息:net.Read()
- 发送文件内容:os.Open()、os.Read()、net.Write()、os.Close()
- 关闭连接:net.Close()
接收方:服务端
- 监听连接请求:net.Listen()
- 接受连接请求:net.Accept()
- 接收文件名:net.Read()
- 发送,接收到文件名后的响应信息:net.Write()
- 接收文件内容:os.Create()、net.Read()、os.Write()、os.Close()
- 关闭连接:net.Close()
代码(有详细注释)
recv.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| package main
import ( "fmt" "io" "net" "os" )
func recv_file(file_name string, conn net.Conn) { file, create_error := os.Create(file_name) if create_error != nil { fmt.Println("os.Create():", create_error) return }
defer file.Close()
buffer := make([]byte, 1024) for { read_count, read_error := conn.Read(buffer) if read_error != nil { if read_error == io.EOF { fmt.Println("接收完成:", read_error) } else { fmt.Println("net.Read():", read_error) }
return } file.Write(buffer[:read_count]) } }
func main() { listener, listen_error := net.Listen("tcp4", "127.0.0.1:8000") if listen_error != nil { fmt.Println("net.Listen():", listen_error) return }
defer listener.Close()
conn, accept_error := listener.Accept() if accept_error != nil { fmt.Println("net.Accept():", accept_error) return }
defer conn.Close()
buffer := make([]byte, 1024) read_count, read_error := conn.Read(buffer) if read_error != nil { fmt.Println("net.Read():", read_error) return }
file_name := string(buffer[:read_count])
conn.Write([]byte("ok"))
recv_file(file_name, conn) }
|
send.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| package main
import ( "fmt" "io" "net" "os" )
func send_file(file_path string, conn net.Conn) { file, open_error := os.Open(file_path) if open_error != nil { fmt.Println("os.Open():", open_error) return }
defer file.Close()
buffer := make([]byte, 1024) for { read_count, read_error := file.Read(buffer) if read_error != nil { if read_error == io.EOF { fmt.Println("发送完成:", read_error) } else { fmt.Println("os.Read()", read_error) }
return }
conn.Write(buffer[:read_count]) } }
func main() { fmt.Print("请输入完整文件路径:") var file_path string fmt.Scan(&file_path)
file_info, stat_error := os.Stat(file_path) if stat_error != nil { fmt.Println("os.Stat():", stat_error) return }
conn, dial_error := net.Dial("tcp4", "127.0.0.1:8000") if dial_error != nil { fmt.Println("net.Dial():", dial_error) return }
defer conn.Close()
_, write_error := conn.Write([]byte(file_info.Name())) if write_error != nil { fmt.Println("net.Write():", write_error) return }
buffer := make([]byte, 1024) read_count, read_error := conn.Read(buffer) if read_error != nil { fmt.Println("net.Read():", read_error) return }
if string(buffer[:read_count]) == "ok" { send_file(file_path, conn) } }
|
结果
send.go:
1 2 3 4
| PS C:\Users\DSHH\Desktop\go_test> go run send.go 请输入完整文件路径:C:\Users\DSHH\Desktop\temp.txt 发送完成: EOF PS C:\Users\DSHH\Desktop\go_test>
|
recv.go:
1 2 3
| PS C:\Users\DSHH\Desktop\go_test> go run recv.go 接收完成: EOF PS C:\Users\DSHH\Desktop\go_test>
|
总结
Go网络编程的学习代码示例:网络文件传输。
参考资料
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获