利用tcp协议,建立发送端与接收端的连接,通过这个连接,以字节切片的形式,完成文件传输。
一、发送端
发送端主要步骤为:
1.建立与接收端的连接;
2.读取文件信息;
3.向接收端传递文件名;
4.读取接收端返回的指令,若为OK,则执行文件传输;
5.以字节切片循环读取文件内容,使用连接将文件内容传送到接收端。
package main
import (
"fmt"
"io"
"net"
"os"
)
func main() {
//获取命令行参数,用命令传递文件go run send.go D:\1.mp3,参数为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
}
//发送文件名到接收端
_, err = conn.Write([]byte(filename))
if err != nil {
fmt.Println("conn.Write err", err)
return
}
buf := make([]byte, 4096)
//接收服务器返还的指令
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) {
//打开要传输的文件
file, err := os.Open(filepath)
if err != nil {
fmt.Println("os.Open err", err)
return
}
buf := make([]byte, 4096)
//循环读取文件内容,写入远程连接
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
}
}
}
二、接收端
接收端的主要内容是:
1.建立监听服务,等待连接;
2.获取发送端的连接,读取请求数据,获取文件名,返回“ok”给发送端;
3.创建一个新的文件;
4.循环读取连接中发送来的信息,将其写入到创建的新文件中。
package main
import (
"fmt"
"net"
"os"
)
func main() {
//创建监听服务
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
}
/**
读取文件名,向文件发送者返回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
}
/**
创建文件并写入文件内容
*/
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])
}
}