go TCP传输文件

楔子

学习 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
}

其余代码

发布了308 篇原创文章 · 获赞 70 · 访问量 38万+

猜你喜欢

转载自blog.csdn.net/u012848709/article/details/104107396
今日推荐