Server side:
package main import ( "bufio" "encoding/binary" "fmt" "net" "os" "unsafe" ) func SHandleError(err error, when string) { if err != nil{ fmt.Println("服务端异常退出,err=", err, when) os.Exit(1) } } func BytesToInt64(buf []byte) int64 { return int64(binary.BigEndian.Uint64(buf)) } func main() { //建立tcp监听 listener, e := net.Listen("tcp", ":8080") SHandleError(e, "net.Listen") defer func() { listener.Close() fmt.Println("服务端正常退出") // Accept the client request, establish a session dedicated line Conn } () conn, e: = listener.Accept () SHandleError (e, "listener.Accept") defer func () { conn.Close () fmt.Printf ("The link with% v has been disconnected \ n", conn.RemoteAddr ()) } () dstFile, e: = os.OpenFile (`meinv1.mp4`, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, 0666) writer: = bufio.NewWriter (dstFile) defer dstFile.Close () buffer: = make ([] byte, 100) total: = 0 // Accept the size of the file to be sent from the client buffer2: = make ([] byte, 10) m, e: = conn.Read (buffer2) / / size: = string (buffer2 [: m]) //fmt.Printf("%s\n",size) // i, _: = strconv.Atoi (size) // [] byte converted to int64 i: = BytesToInt64 (buffer2 [: m]) fmt.Printf ("% d,% T \ n", i, i) // int64 converted to int j: = * (* int) (unsafe.Pointer (& i)) fmt.Printf ("% d,% T \ n", j, j) for { // accept files uploaded by the client n, e: = conn.Read (buffer) SHandleError (e, "conn.Read") total + = n // Write to the server local file writer.Write (buffer [: n]) writer.Flush () fmt. Printf ("Successfully written% d bytes, a total of% d bytes \ n", n, total) // If the actual total number of received bytes is equal to the number of bytes to be transmitted by the client, it means the transmission is completed if total == j { fmt.Println ("File accepted successfully, total", total, "byte") // Responded that the client has received the file conn.Write ([] byte ("File accepted successfully")) break } } }
client side:
package main import ( "bufio" "encoding/binary" "fmt" "io" "net" "os" "time" ) /* ·实现tcp文件上传功能 */ func CHandleError2(err error, when string) { if err != nil { fmt.Println("客户端异常退出:err=", err, when) os.Exit(1) } } func Int64ToBytes(i int64) []byte { var buf = make([]byte, 8) binary.BigEndian.PutUint64(buf, uint64(i)) return buf } func main() { conn, e := net.Dial("tcp", "127.0.0.1:8080") CHandleError2(e, "net.Dial") fmt.Println ("Client exits normally") defer func () { conn.Close() } () // Get the size of the target file and pass it to the server fileInfo, _: = os.Stat (`perfect.mp4`) size: = fileInfo.Size () bytes: = Int64ToBytes (size) conn.Write (bytes ) // Temporarily solve the sticky packet problem through the client ’s sleep 200 milliseconds, and can also be resolved through tcp reconnection. Later, use (packet header + data) to encapsulate the data packet. Time.Sleep (time.Millisecond * 200) buffer: = make ([] byte, 100) srcFile, _: = os.Open (`perfect.mp4`) reader: = bufio.NewReader (srcFile) total: = 0 for { n, err: = reader.Read (buffer) fmt .Println (n, err) if err == io.EOF { fmt.Println ("File sent completed") fmt.Println (total) break } else { _, e = conn.Write (buffer [: n]) total + = n CHandleError2 (e, "conn.Write") } } n, e := conn.Read(buffer) CHandleError2(e, "conn.Read") replyMsg := buffer[:n] fmt.Println("服务端:", string(replyMsg)) }