日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

golang文件传输服务

發布時間:2024/5/24 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 golang文件传输服务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

續上篇,本篇介紹一個完整的golang文件傳輸服務器。

完整的代碼可以看服務器,客戶端

網絡使用的框架如上篇介紹,這里就不再復述.

首先定義3個命令碼:

const (
    request_file = 1
    file_size = 2
    transfering = 3
)

request_file用于請求文件傳輸,附帶的命令參數是文件key.

file_size用于通告客戶端文件的大小.

transfering用于傳輸文件內容,附帶參數是文件內容的二進制數據.

服務器的文件配置示例

../learnyouhaskell.pdf=haskell
../golang.1.1.2.chm=golang
../NodeJS.pdf=NodeJS

上面的文件配置了3個文件可供傳輸=左邊是文件路徑,右邊是請求文件時使用的key.

服務器啟動時首先調用loadfile將文件導入到內存中,然后根據定義的key,將文件內容插入到字典filemap中:

func loadfile(){
    //從配置導入文件
    F,err := os.Open("./config.txt")
    if err != nil {
        fmt.Printf("config.txt open failed
")
        return
    }
    filemap = make(map[string][]byte)
    bufferReader := bufio.NewReader(F)
    eof := false
    for !eof {
        line,err := bufferReader.ReadString('
')
        if err == io.EOF{
            err = nil
            eof = true
        }else if err != nil{
            fmt.Printf("parse file error
")
            return
        }
        if len(line) > 1 {
            line = line[0:len(line)-1]//drop '
'
            fileconfig := strings.Split(line,"=")
            if len(fileconfig) == 2 {
                buf, err := ioutil.ReadFile(fileconfig[0])
                if err != nil {
                    fmt.Printf("%s load error
",fileconfig[0])
                }else{  
                    filemap[fileconfig[1]] = buf
                    fmt.Printf("%s load success,key %s
",fileconfig[0],fileconfig[1])
                }
            }
        }
    }

    if filemap["golang"] == nil {
        fmt.Printf("golang not found
")
    }

    fmt.Printf("loadfile finish
") 
}

接著是服務其的packet_handler:

func process_client(session *tcpsession.Tcpsession,rpk *packet.Rpacket){
    cmd,_ := rpk.Uint16()
    if cmd == request_file {
        if session.Ud() != nil {
            fmt.Printf("already in transfer session
")
        }else
        {
            filename,_ := rpk.String()
            filecontent := filemap[filename]
            if filecontent == nil {
                fmt.Printf("%s not found
",filename)
                session.Close()
            }else{
                fmt.Printf("request file %s
",filename)
                tsession := &transfer_session{filecontent:filecontent,ridx:0}
                session.SetUd(tsession)

                wpk := packet.NewWpacket(packet.NewByteBuffer(64),false)
                wpk.PutUint16(file_size)
                wpk.PutUint32(uint32(len(filecontent)))
                session.Send(wpk,nil)
                tsession.send_file(session)
            }   
        }
    }else{
        fmt.Printf("cmd error,%d
",cmd)
        session.Close()
    }
}

如果收到的消息是requestfile,首先查看請求的文件是否存在,如果存在則創建一個文件傳輸過程transfersession,

并將它與tcpsession綁定,然后發出一個文件大小通告包,緊接著立即調用send_file開始發送文件內容.

func (this *transfer_session)send_file(session *tcpsession.Tcpsession){
    remain := len(this.filecontent) - this.ridx
    sendsize := 0
    if remain >= 16000 {
        sendsize = 16000
    }else{
        sendsize = remain
    }
    wpk := packet.NewWpacket(packet.NewByteBuffer(uint32(sendsize)),false)
    wpk.PutUint16(transfering)
    wpk.PutBinary(this.filecontent[this.ridx:this.ridx+sendsize])
    session.Send(wpk,send_finish)
    this.ridx += sendsize
}

sendfile中根據當前發送位置判斷還有多少內容需要發送,如果剩余內容小于16000字節就將所剩數據一次性

發出,否則 發送16000字節的數據,并調整發送位置。注意到Send函數帶了一個sendfinish函數作為參數,其作用

是當數據包發送 完成后回調send_finish函數.

func send_finish (s interface{},wpk *packet.Wpacket){
    session := s.(*tcpsession.Tcpsession)
    tsession := session.Ud().(*transfer_session)
    if tsession.check_finish(){
        session.Close()
        return
    }
    tsession.send_file(session)
}

send_finish的作用是判斷文件是否已經發送完,如果發完斷開連接,否則接著發送剩余部分.

總結一下,golang用來編寫服務器應用還是相當方便的,很多細節問題在語言層面或系統庫里已經幫你解決掉了

,可以將主要的 精力放在邏輯的處理上.

總結

以上是生活随笔為你收集整理的golang文件传输服务的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。