利用tcp協(xié)議,建立發(fā)送端與接收端的連接,通過(guò)這個(gè)連接,以字節(jié)切片的形式,完成文件傳輸。
一、發(fā)送端
發(fā)送端主要步驟為:
1.建立與接收端的連接;
2.讀取文件信息;
3.向接收端傳遞文件名;
4.讀取接收端返回的指令,若為OK,則執(zhí)行文件傳輸;
5.以字節(jié)切片循環(huán)讀取文件內(nèi)容,使用連接將文件內(nèi)容傳送到接收端。
package main
import (
"fmt"
"io"
"net"
"os"
)
func main() {
//獲取命令行參數(shù),用命令傳遞文件go run send.go D:\1.mp3,參數(shù)為1:send.go,2:D:\1.mp3
list := os.Args
//文件路徑
filepath := list[1]
//文件屬性
fileInfo, err := os.Stat(filepath)
if err != nil {
fmt.Println("os.Stat err", err)
return
}
filename := fileInfo.Name()
/**
建立連接
*/
conn, err := net.Dial("tcp", "127.0.0.1:8003")
if err != nil {
fmt.Println("net.Dialt err", err)
return
}
//發(fā)送文件名到接收端
_, err = conn.Write([]byte(filename))
if err != nil {
fmt.Println("conn.Write err", err)
return
}
buf := make([]byte, 4096)
//接收服務(wù)器返還的指令
n, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err", err)
return
}
//返回ok,可以傳輸文件
if string(buf[:n]) == "ok" {
sendFile(conn, filepath)
}
}
func sendFile(conn net.Conn, filepath string) {
//打開要傳輸?shù)奈募? file, err := os.Open(filepath)
if err != nil {
fmt.Println("os.Open err", err)
return
}
buf := make([]byte, 4096)
//循環(huán)讀取文件內(nèi)容,寫入遠(yuǎn)程連接
for {
n, err := file.Read(buf)
if err == io.EOF {
fmt.Println("文件讀取完畢")
return
}
if err != nil {
fmt.Println("file.Read err:", err)
return
}
_, err = conn.Write(buf[:n])
if err != nil {
fmt.Println("conn.Write err:", err)
return
}
}
}
二、接收端
接收端的主要內(nèi)容是:
1.建立監(jiān)聽服務(wù),等待連接;
2.獲取發(fā)送端的連接,讀取請(qǐng)求數(shù)據(jù),獲取文件名,返回“ok”給發(fā)送端;
3.創(chuàng)建一個(gè)新的文件;
4.循環(huán)讀取連接中發(fā)送來(lái)的信息,將其寫入到創(chuàng)建的新文件中。
package main
import (
"fmt"
"net"
"os"
)
func main() {
//創(chuàng)建監(jiān)聽服務(wù)
listener, err := net.Listen("tcp", "127.0.0.1:8003")
if err != nil {
fmt.Println("net.Listen err:", err)
return
}
/**
等待接受連接
*/
conn, err := listener.Accept()
if err != nil {
fmt.Println("listener.Accept err:", err)
return
}
/**
讀取文件名,向文件發(fā)送者返回OK
*/
buf := make([]byte, 4096)
n, err := conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
filename := string(buf[:n])
fmt.Println("filename:", filename)
if filename != "" {
_, err = conn.Write([]byte("ok"))
if err != nil {
fmt.Println("conn.Write err:", err)
return
}
} else {
return
}
/**
創(chuàng)建文件并寫入文件內(nèi)容
*/
fmt.Println(filename)
file, err := os.Create(filename)
if err != nil {
fmt.Println("os.Create err:", err)
return
}
for {
n, err := conn.Read(buf)
if n == 0 {
fmt.Println("文件讀取完畢")
break
}
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
file.Write(buf[:n])
}
}