楔子
学习 314_尚硅谷_Go核心编程_海量用户通讯系统 在其基础上实现 登录后文件传输到服务器。
遇到了问题,自定义了报文格式,如何实现文件传输。使用 网络传输Byte数组最简单的就是用base64对byte数组进行编码,进过编码后得到String传输到对端解码得出byte数组
go base64编解码
package main
import (
"encoding/base64"
"fmt"
)
func main() {
base64encode()
}
func base64encode() {
bytes := []byte("hello 编解码")
encodeToString := base64.StdEncoding.EncodeToString(bytes)
fmt.Println(bytes, "编码后的内容为", encodeToString)
fmt.Println("解码")
decodeString, err := base64.StdEncoding.DecodeString(encodeToString)
fmt.Println(decodeString, "|", err)
}
文件传输
客户端发送
package process
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
"study/qq/client/utils"
"study/qq/common/message"
)
/********************************************
|客户端发送数据到服务器
*********************************************/
// 发送文件到服务器
type SendFileToServer struct {
}
func (this *SendFileToServer) sendFile(filePath string) (err error) {
fileInfo, err := os.Stat(filePath)
if err != nil {
fmt.Println("输入文件路径错误", err)
return
}
fileName := fileInfo.Name()
fileSize := fileInfo.Size()
fmt.Println("发送的文件名是:", fileName)
var mes message.Message
mes.Type = message.SendFileMesType
open, err := os.Open(filePath)
if err != nil {
fmt.Println(err)
return err
}
defer open.Close()
var count int64
//传输数据
for {
buf := make([]byte, 1024)
// 读取文件内容
readN, err := open.Read(buf)
if err != nil && err == io.EOF {
fmt.Println("文件传输完成")
//通知服务器文件传输结束
//conn.Write([]byte("finish"))
break
}
//发送到服务端
var fileMes message.SendFileMes
fileMes.FileName = fileName
//多读取到的文件进行编码
encodeToString := base64.StdEncoding.EncodeToString(buf[:readN])
fileMes.FileContext = encodeToString
data, err := json.Marshal(fileMes)
if err != nil {
fmt.Println("文件传输序列化错误", err)
return err
}
mes.Data = string(data)
data, err = json.Marshal(mes)
if err != nil {
fmt.Println("文件传输序列化错误", err)
return err
}
tr := &utils.Transfer{
Conn: CurUser.Conn,
}
err = tr.WritePkg(data)
count += int64(readN)
sendPercent := float64(count) / float64(fileSize) * 100
value := fmt.Sprintf("%.2f", sendPercent)
//打印上传进度
fmt.Println("文件上传:" + value + "%")
}
return
}
服务端
func (this *SendFileProcess) ReceiveFile(mes *message.Message) (err error) {
var fileMes message.SendFileMes
err = json.Unmarshal([]byte(mes.Data), &fileMes)
if err != nil {
fmt.Println("~ReceiveFile~", err)
return
}
fmt.Println("传输的文件是:", fileMes.FileName)
openFile, err := os.OpenFile("d:/pic/"+utils2.GetDateStr()+fileMes.FileName, os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
fmt.Println("打开文件错误", err)
return
}
defer openFile.Close()
//发送使用了base64 编码,现在解码
decodeString, err := base64.StdEncoding.DecodeString(fileMes.FileContext)
if err != nil {
fmt.Println("服务器接收文件base64解码错误", err)
return
}
openFile.Write(decodeString)
return
}
其余代码