您现在的位置是:首页 >技术交流 >Go网络编程的学习代码示例:网络文件传输网站首页技术交流
Go网络编程的学习代码示例:网络文件传输
简介Go网络编程的学习代码示例:网络文件传输
前言
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
package main
import (
"fmt"
"io" // 文件相关
"net"
"os" // 操作系统/文件相关
)
// 五、接收文件内容
func recv_file(file_name string, conn net.Conn) {
file, create_error := os.Create(file_name) // 在当前路径下创建文件
// 返回值:File结构体
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 {
// 注意:读取完成时,会读取到EOF文件结束标志,错误标志置位为“EOF”,需要进行额外判断
if read_error == io.EOF {
fmt.Println("接收完成:", read_error)
} else {
fmt.Println("net.Read():", read_error)
}
return // 注意:接收完成和出现错误两种情况,函数返回,其他情况持续向本地写入文件
}
// if n == 0 { //对端断开,出问题
// fmt.Println("接收完毕2")
// break
// }
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
}
// 六、2.关闭连接
defer listener.Close()
// 二、接受连接请求
conn, accept_error := listener.Accept()
if accept_error != nil {
fmt.Println("net.Accept():", accept_error)
return
}
// 六、1.关闭连接
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
package main
import (
"fmt"
"io" // 文件相关
"net"
"os" // 操作系统/文件相关
)
// 五、发送文件内容
func send_file(file_path string, conn net.Conn) {
file, open_error := os.Open(file_path) // 打开文件
// 返回值:File结构体
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 {
// 注意:读取完成时,会读取到EOF文件结束标志,错误标志置位为“EOF”,需要进行额外判断
if read_error == io.EOF {
fmt.Println("发送完成:", read_error)
} else {
fmt.Println("os.Read()", read_error)
}
return // 注意:发送完成和出现错误两种情况,函数返回,其他情况持续向网络写入文件
}
conn.Write(buffer[:read_count]) // 网络写入文件,按字节
}
}
func main() {
// 一、1.接收用户输入,获取完整文件路径。如:C:UsersDSHHDesktop emp.txt
fmt.Print("请输入完整文件路径:")
var file_path string
fmt.Scan(&file_path)
// 一、2.提取文件信息
file_info, stat_error := os.Stat(file_path)
// 返回值:FileInfo = fs.FileInfo接口类型
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()))
// Name()返回string,如:temp.txt,转换为byte切片在网络中传输
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" { // 注意:网络接收为byte字节序列,需要转换为string类型才能作比较
send_file(file_path, conn)
// 注意,参数使用完整文件路径而不是文件名,因为后续需要在指定路径打开文件
}
}
结果
send.go:
PS C:UsersDSHHDesktopgo_test> go run send.go
请输入完整文件路径:C:UsersDSHHDesktop emp.txt
发送完成: EOF
PS C:UsersDSHHDesktopgo_test>
recv.go:
PS C:UsersDSHHDesktopgo_test> go run recv.go
接收完成: EOF
PS C:UsersDSHHDesktopgo_test>
总结
Go网络编程的学习代码示例:网络文件传输。
参考资料
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。