国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Golang - golang socket斷點續傳大文件的實現方法

golang socket斷點續傳大文件的實現方法

2020-05-26 10:47Tab609 Golang

今天小編就為大家分享一篇golang socket斷點續傳大文件的實現方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

在日常編程中,我們肯定會遇到用socket傳送文件內容,如果是大文件的,總不能傳送到一半因某原因斷掉了,又從新傳送文件內容吧。對,我們需要續傳,也就是接著上次傳送的位置繼續發送文件內容。

續傳的話,其實并不難,我理解的思路大概如下:

客戶端發送消息詢問服務端,你上次接收到的文件內容位置

服務端告訴客戶端上次接收到的文件內容位置

客戶端就從上次斷點的位置繼續發送文件內容

客戶端發送文件內容完畢后通知服務端,然后斷開連接

下面我們看看代碼的實現

服務端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// file name: server.go
 
package main
 
import (
 "os"
 "io"
 "net"
 "log"
 "strconv"
 // "time"
)
 
// 把接收到的內容append到文件
func writeFile(content []byte) {
 if len(content) != 0 {
  fp, err := os.OpenFile("test_1.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0755)
  defer fp.Close()
  if err != nil {
   log.Fatalf("open file faild: %s\n", err)
  }
  _, err = fp.Write(content)
  if err != nil {
   log.Fatalf("append content to file faild: %s\n", err)
  }
  log.Printf("append content: 【%s】 success\n", string(content))
 }
}
 
// 獲取已接收內容的大小
// (斷點續傳需要把已接收內容大下通知客戶端從哪里開始發送文件內容)
func getFileStat() int64 {
 fileinfo, err := os.Stat("test_1.txt")
 if err != nil {
  // 如果首次沒有創建test_1.txt文件,則直接返回0
  // 告訴客戶端從頭開始發送文件內容
  if os.IsNotExist(err) {
   log.Printf("file size: %d\n", 0)
   return int64(0)
  }
  log.Fatalf("get file stat faild: %s\n", err)
 }
 log.Printf("file size: %d\n", fileinfo.Size())
 return fileinfo.Size()
}
 
func serverConn(conn net.Conn) {
 defer conn.Close()
 for {
  var buf = make([]byte, 10)
  n, err := conn.Read(buf)
  if err != nil {
   if err == io.EOF {
    log.Println("server io EOF\n")
    return
   }
   log.Fatalf("server read faild: %s\n", err)
  }
  log.Printf("recevice %d bytes, content is 【%s】\n", n, string(buf[:n]))
  // 判斷客戶端發送過來的消息
  // 如果是'start-->‘則表示需要告訴客戶端從哪里開始讀取文件數據發送
  switch string(buf[:n]) {
  case "start-->":
   off := getFileStat()
   // int conver string
   stringoff := strconv.FormatInt(off, 10)
   _, err = conn.Write([]byte(stringoff))
   if err != nil {
    log.Fatalf("server write faild: %s\n", err)
   }
   continue
  case "<--end":
   // 如果接收到客戶端通知所有文件內容發送完畢消息則退出
   log.Fatalf("receive over\n")
   return
  // default:
  //  time.Sleep(time.Second * 1)
  }
  // 把客戶端發送的內容保存到文件
  writeFile(buf[:n])
 }
}
 
func main() {
 // 建立監聽
 l, err := net.Listen("tcp", ":8888")
 if err != nil {
  log.Fatalf("error listen: %s\n", err)
 }
 defer l.Close()
 
 log.Println("waiting accept.")
 // 允許客戶端連接,在沒有客戶端連接時,會一直阻塞
 conn, err := l.Accept()
 if err != nil {
  log.Fatalf("accept faild: %s\n", err)
 }
 serverConn(conn)
}

客戶端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// file name: client.go
 
package main
 
import (
 "os"
 "io"
 "net"
 "log"
 "time"
 "strconv"
)
 
// 獲取服務端發送的消息
func clientRead(conn net.Conn) int {
 buf := make([]byte, 5)
 n, err := conn.Read(buf)
 if err != nil {
  log.Fatalf("receive server info faild: %s\n", err)
 }
 // string conver int
 off, err := strconv.Atoi(string(buf[:n]))
 if err != nil {
  log.Fatalf("string conver int faild: %s\n", err)
 }
 return off
}
 
// 發送消息到服務端
func clientWrite(conn net.Conn, data []byte) {
 _, err := conn.Write(data)
 if err != nil {
  log.Fatalf("send 【%s】 content faild: %s\n", string(data), err)
 }
 log.Printf("send 【%s】 content success\n", string(data))
}
 
// client conn
func clientConn(conn net.Conn) {
 defer conn.Close()
 
 // 發送"start-->"消息通知服務端,我要開始發送文件內容了
 // 你趕緊告訴我你那邊已經接收了多少內容,我從你已經接收的內容處開始繼續發送
 clientWrite(conn, []byte("start-->"))
 off := clientRead(conn)
 
 // send file content
 fp, err := os.OpenFile("test.txt", os.O_RDONLY, 0755)
 if err != nil {
  log.Fatalf("open file faild: %s\n", err)
 }
 defer fp.Close()
 
 // set file seek
 // 設置從哪里開始讀取文件內容
 _, err = fp.Seek(int64(off), 0)
 if err != nil {
  log.Fatalf("set file seek faild: %s\n", err)
 }
 log.Printf("read file at seek: %d\n", off)
 
 for {
  // 每次發送10個字節大小的內容
  data := make([]byte, 10)
  n, err := fp.Read(data)
  if err != nil {
   if err == io.EOF {
    // 如果已經讀取完文件內容
    // 就發送'<--end'消息通知服務端,文件內容發送完了
    time.Sleep(time.Second * 1)
    clientWrite(conn, []byte("<--end"))
    log.Println("send all content, now quit")
    break
   }
   log.Fatalf("read file err: %s\n", err)
  }
  // 發送文件內容到服務端
  clientWrite(conn, data[:n])
 }
}
 
func main() {
 // connect timeout 10s
 conn, err := net.DialTimeout("tcp", ":8888", time.Second * 10)
 if err != nil {
  log.Fatalf("client dial faild: %s\n", err)
 }
 clientConn(conn)
 }

客戶端讀取文件test.txt內容發送到服務端,服務端把接收到的文件內容保存在test_1.txt文件中。我們模擬斷點續傳的方式是:

第一次先發送test.txt文件內容到服務端

修改test.txt文件,加一些內容

再次運行server socket以及client socket,觀察客戶端是不是只發送新增的文件內容到服務端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 假設我的test.txt文件有以下內容
$ cat test.txt
hello golang.
 
# 先運行server socket再運行client socket(分別在兩個終端窗口運行)
$ go run server.go
$ go run client.go
 
# 服務端會輸出以下內容
2018/04/05 23:37:13 waiting accept.
2018/04/05 23:37:15 recevice 8 bytes, content is 【start-->】
2018/04/05 23:37:15 file size: 0
2018/04/05 23:37:15 recevice 10 bytes, content is 【hello gola】
2018/04/05 23:37:15 append content: 【hello gola】 success
2018/04/05 23:37:15 recevice 2 bytes, content is 【n.】
2018/04/05 23:37:15 append content: 【n.】 success
2018/04/05 23:37:16 recevice 6 bytes, content is 【<--end】
2018/04/05 23:37:16 receive over
exit status 1
 
# 客戶端會輸出如下內容
2018/04/05 23:37:15 send 【start-->】 content success
2018/04/05 23:37:15 read file at seek: 0
2018/04/05 23:37:15 send 【hello gola】 content success
2018/04/05 23:37:15 send 【n.】 content success
2018/04/05 23:37:16 send 【<--end】 content success
2018/04/05 23:37:16 send all content, now quit
 
# 這時候我們看看test_1.txt內容跟test.txt完全一致
$ cat test_1.txt
hello golan.
 
# ------- 模擬斷點續傳 ----------
# 現在我們往test.txt追加內容: hello python.
$ cat test.txt
hello golang.
hello python.
 
# 我們再一次運行server socket 和 client socket(分別在兩個終端窗口運行)
$ go run server.go
$ go run client.go
 
# 服務端會輸出以下內容
2018/04/05 23:44:31 waiting accept.
2018/04/05 23:44:34 recevice 8 bytes, content is 【start-->】
2018/04/05 23:44:34 file size: 12
2018/04/05 23:44:34 recevice 10 bytes, content is 【
hello pyt】
2018/04/05 23:44:34 append content: 【
hello pyt】 success
2018/04/05 23:44:34 recevice 4 bytes, content is 【hon.】
2018/04/05 23:44:34 append content: 【hon.】 success
2018/04/05 23:44:35 recevice 6 bytes, content is 【<--end】
2018/04/05 23:44:35 receive over
exit status 1
# 服務端在接收到客戶端發送的 start--> 信息后會獲取上次接收到文件內容位置,并通知客戶端(這里file size 是12)
 
# 客戶端會輸出以下內容
2018/04/05 23:44:34 send 【start-->】 content success
2018/04/05 23:44:34 read file at seek: 12
2018/04/05 23:44:34 send 【
hello pyt】 content success
2018/04/05 23:44:34 send 【hon.】 content success
2018/04/05 23:44:35 send 【<--end】 content success
2018/04/05 23:44:35 send all content, now quit
# 我們客戶端獲取到了服務端返回的文件位置,通過 Seek 來指定從哪里開始讀取文件
# 通過日志可以看到我們客戶端只發送了后面追加的內容: hello python. 到服務端
 
# 我們看看此時test_1.txt文件的內容是否跟test.txt一致
$ cat test_1.txt
hello golang.
hello python.

以上這篇golang socket斷點續傳大文件的實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/luckytanggu/article/details/79830493

延伸 · 閱讀

精彩推薦
  • Golanggolang如何使用struct的tag屬性的詳細介紹

    golang如何使用struct的tag屬性的詳細介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細介紹,從例子說起,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看...

    Go語言中文網11352020-05-21
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang json.Marshal 特殊html字符被轉義的解決方法

    golang json.Marshal 特殊html字符被轉義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉義的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggo日志系統logrus顯示文件和行號的操作

    go日志系統logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統logrus顯示文件和行號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • GolangGolang中Bit數組的實現方式

    Golang中Bit數組的實現方式

    這篇文章主要介紹了Golang中Bit數組的實現方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    天易獨尊11682021-06-09
  • GolangGolang通脈之數據類型詳情

    Golang通脈之數據類型詳情

    這篇文章主要介紹了Golang通脈之數據類型,在編程語言中標識符就是定義的具有某種意義的詞,比如變量名、常量名、函數名等等,Go語言中標識符允許由...

    4272021-11-24
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggolang的httpserver優雅重啟方法詳解

    golang的httpserver優雅重啟方法詳解

    這篇文章主要給大家介紹了關于golang的httpserver優雅重啟的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    helight2992020-05-14
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久草视频网 | 午夜在线 | 亚洲精品片 | 国产精品久久久久久久久久三级 | 日韩欧美国产一区二区 | 午夜激情影院 | 欧美日韩一区精品 | 精品一区二区在线观看 | 99这里只有精品视频 | 亚洲精品久久久一区二区三区 | 国内自拍视频在线观看 | 精品第一页| 91在线在线 | 亚洲视频中文字幕 | 国产欧美日韩精品一区 | 日本一区二区电影 | 韩国精品免费视频 | 最新中文字幕在线 | 免费成人av| 一区二区国产视频 | av在线黄| 精品一区二区三区中文字幕老牛 | 国产精品不卡在线播放 | 亚洲精品一区在线观看 | 亚洲高清一区二区三区 | 在线观看国产视频 | 久久久久国产精品免费免费搜索 | 日韩激情免费视频 | 欧美三级网址 | 亚洲精品视频专区 | 99久久久国产精品 | 亚洲视频1区 | 久久九 | 黄色一级片免费 | 一级免费毛片 | 亚洲人免费视频 | 蜜桃精品在线 | 人人干天天干 | 国产精品视频免费观看 | 国产精品高清在线 | 激情综合网婷婷 |