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
}

其餘代碼

發佈了286 篇原創文章 · 獲贊 63 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章