package main
import (
"bufio"
"encoding/binary"
"fmt"
"net"
"os"
"unsafe"
)
func SHandleError(err error, when string) {
if err != nil{
if when == "conn.Read" {
fmt.Println("读取客户端数据异常,客户端断开")
}else{
fmt.Println("服务端异常退出,err=", err, when)
os.Exit(1)
}
}
}
func BytesToInt64(buf []byte) int64 {
return int64(binary.BigEndian.Uint64(buf))
}
func HandleConn(conn net.Conn) {
defer func() {
conn.Close()
fmt.Printf("已断开与%v的链接\n", conn.RemoteAddr())
}()
//接受客户端发来的要传文件大小
buffer2 := make([]byte, 10)
m, e := conn.Read(buffer2)
SHandleError(e, "listener.Accept")
//[]byte转换为int64
i := BytesToInt64(buffer2[:m])
//int64转换为int
j := *(*int)(unsafe.Pointer(&i))
fmt.Printf("%d, %T\n",j,j)
//接受客户端发来的要传文件名称字符串
buffer3 := make([]byte, 1000)
m1, _ := conn.Read(buffer3)
fmt.Printf("%s \n",buffer3[:m1])
fmt.Printf(string(buffer3[:m1]))
dstFile, e := os.OpenFile(string(buffer3[:m1]), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
writer := bufio.NewWriter(dstFile)
defer dstFile.Close()
buffer := make([]byte, 512)
total := 0
for {
//接受客户端上传的文件
n, e := conn.Read(buffer)
if e != nil {
fmt.Println("读取客户端数据异常,客户端断开")
break
}
total += n
//写入服务端本地文件
writer.Write(buffer[:n])
writer.Flush()
fmt.Printf("成功写入%d字节, 共%d字节, 进度 %d \n", n, total, 100*total/j)
//如果实际总接受字节数与客户端给的要传输字节数相等,说明传输完毕
if total == j{
fmt.Println("文件接受成功,共",total,"字节: ", string(buffer3[:m1]))
//回复客户端已收到文件
conn.Write([]byte("文件接受成功"))
break
}
}
}
func main() {
listen, e := net.Listen("tcp", "0.0.0.0:8081")
SHandleError(e, "net.Listen")
defer func() {
listen.Close()
fmt.Println("服务端正常退出")
}()
for {
conn, err := listen.Accept()
if err != nil {
fmt.Println(err)
continue // 继续监听
}
go HandleConn(conn)
}
}