Server端main.go
package main
import (
"encoding/binary"
"fmt"
"io"
"net"
"time"
)
func HandleException(e error) {
if e != nil {
panic(e.Error())
}
}
func main() {
addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
HandleException(err)
listener, err := net.ListenTCP("tcp", addr)
HandleException(err)
fmt.Println("server listening on localhost:8080...")
for {
conn, err1 := listener.Accept()
HandleException(err1)
go func(connection net.Conn) {
defer connection.Close()
defer fmt.Println("==========connection closed=========")
fmt.Println("==========connection on=========")
for {
errt := connection.SetReadDeadline(time.Now().Add(time.Second * 30))
if errt != nil {
fmt.Println("set time out failure")
return
}
fmt.Println("================================")
lenBuf, err2 := readData(conn, 4)
if err2 != nil {
if err2 == io.EOF {
fmt.Println("unable to receive the complete packet header, client connection closed...")
} else {
fmt.Println("something wrong happened, receive failure")
fmt.Println(err2)
}
return
}
conLen := binary.BigEndian.Uint32(lenBuf)
if conLen == 0 {
fmt.Println("INFO: shutting down...")
break
}
fmt.Printf("INFO: preparing to receive %d Bytes data...\n", conLen)
dataBuf, err2 := readData(conn, conLen)
if err2 != nil {
if err2 == io.EOF {
fmt.Printf("INFO: client connection closed, unable to load the complete data, received %d Bytes\n", len(dataBuf))
fmt.Println(string(dataBuf))
break
} else {
fmt.Println("INFO: something wrong happened, receive failure")
fmt.Println(err2)
return
}
}
fmt.Printf("INFO: execpted %d Bytes, actual %d Bytes\n", conLen, len(dataBuf))
fmt.Printf("DATA:\n%s\n", string(dataBuf))
}
sendData(conn, []byte("all data loaded"))
}(conn)
}
}
func sendData(conn net.Conn, buf []byte) (n int) {
conLen := make([]byte, 4)
binary.BigEndian.PutUint32(conLen, uint32(len(buf)))
data := append(conLen, buf...)
n, _ = conn.Write(data)
return
}
func readData(conn net.Conn, size uint32) ([]byte, error) {
left := int(size)
var data []byte
for left > 0 {
tmp := make([]byte, left)
if n, err := conn.Read(tmp); err == nil {
left -= n
data = append(data, tmp...)
} else {
if err == io.EOF {
data = append(data, tmp...)
return data, err
} else {
return nil, err
}
}
}
return data, nil
}
Client端main.go
package main
import (
"bufio"
"encoding/binary"
"fmt"
"io"
"math/rand"
"net"
"os"
)
func HandleException(e error) {
if e != nil {
panic(e.Error())
}
}
func main() {
serverAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
HandleException(err)
conn, err := net.DialTCP("tcp", nil, serverAddr)
HandleException(err)
defer conn.Close()
file, err := os.OpenFile("./material.txt", os.O_RDONLY, 0666)
HandleException(err)
defer file.Close()
fileReader := bufio.NewReader(file)
for {
size := rand.Intn(1024)
buf := make([]byte, size)
if n, err1 := fileReader.Read(buf); err1 == nil {
n = sendData(conn, buf[:n])
fmt.Printf("client: sent %d Bytes data...\n", n-4)
} else {
if err1 == io.EOF {
n = sendData(conn, buf[:n])
fmt.Printf("client: sent %d Bytes data...\n", n-4)
break
} else {
fmt.Printf("INFO: something wrong happened:\n%+v", err1)
return
}
}
}
fmt.Println("INFO: waiting for response....")
lenBuf, err := readData(conn, 4)
conLen := binary.BigEndian.Uint32(lenBuf)
if conLen == 0 {
return
}
conBuf, err := readData(conn, conLen)
fmt.Printf("server: %s", string(conBuf))
}
func sendData(conn net.Conn, buf []byte) (n int) {
conLen := make([]byte, 4)
binary.BigEndian.PutUint32(conLen, uint32(len(buf)))
data := append(conLen, buf...)
n, _ = conn.Write(data)
return
}
func readData(conn net.Conn, size uint32) ([]byte, error) {
left := int(size)
var data []byte
for left > 0 {
tmp := make([]byte, left)
if n, err := conn.Read(tmp); err == nil {
left -= n
data = append(data, tmp...)
} else {
if err == io.EOF {
data = append(data, tmp...)
return data, err
} else {
return nil, err
}
}
}
return data, nil
}