Last active
May 13, 2019 02:43
-
-
Save SLonger/1d72e2f6cc3b85643118d7752d249265 to your computer and use it in GitHub Desktop.
tcp 粘包处理 server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 参考链接https://feixiao.github.io/2016/05/08/bufio/ | |
package main | |
import ( | |
"bytes" | |
"encoding/binary" | |
"flag" | |
"fmt" | |
"io" | |
"net" | |
"strconv" | |
"time" | |
) | |
var addr = flag.String("addr", "localhost", "The address to listen to; default is \"\" (all interfaces).") | |
var port = flag.Int("port", 8000, "The port to listen on; default is 8000.") | |
type Package struct { | |
Version [2]int8 | |
Datalen int64 | |
Data []byte | |
} | |
func (p *Package) String() string { | |
return fmt.Sprintf("Version:%d DataLen:%d Data:%s", p.Version, p.Datalen, p.Data) | |
} | |
func (p *Package) Pack(w io.Writer) { | |
binary.Write(w, binary.BigEndian, p.Version) | |
binary.Write(w, binary.BigEndian, p.Datalen) | |
binary.Write(w, binary.BigEndian, p.Data) | |
} | |
func (p *Package) Unpack(r io.Reader) { | |
binary.Read(r, binary.BigEndian, &p.Version) | |
binary.Read(r, binary.BigEndian, &p.Datalen) | |
if p.Datalen > 0 { | |
p.Data = make([]byte, p.Datalen) | |
} | |
binary.Read(r, binary.BigEndian, &p.Data) | |
} | |
func BuildMsg(data []byte) Package { | |
var pkg Package | |
pkg.Version[0] = 'V' | |
pkg.Version[1] = '1' | |
pkg.Data = data | |
pkg.Datalen = int64(len(pkg.Data)) | |
fmt.Printf("%+v\n", pkg) | |
return pkg | |
} | |
func main() { | |
flag.Parse() | |
fmt.Println("Starting server...") | |
src := *addr + ":" + strconv.Itoa(*port) | |
listener, _ := net.Listen("tcp", src) | |
fmt.Printf("Listening on %s.\n", src) | |
defer listener.Close() | |
for { | |
conn, err := listener.Accept() | |
if err != nil { | |
fmt.Printf("Some connection error: %s\n", err) | |
} | |
go handleConnection(conn) | |
} | |
} | |
func handleConnection(conn net.Conn) { | |
remoteAddr := conn.RemoteAddr().String() | |
fmt.Println("Client connected from " + remoteAddr) | |
ech := make(chan error) | |
go func(conn net.Conn, ech chan error) { | |
buf := make([]byte, 10) | |
_, err := conn.Read(buf) | |
if err != nil { | |
ech <- err | |
} | |
}(conn, ech) | |
tick := time.NewTicker(2 * time.Second) | |
for { | |
select { | |
case <-tick.C: | |
handleMessage(conn) | |
case err := <-ech: | |
fmt.Println(err) | |
break | |
} | |
} | |
fmt.Println("Client at " + remoteAddr + " disconnected.") | |
} | |
func handleMessage(conn net.Conn) { | |
var buf bytes.Buffer | |
jsonstring := []byte("t") | |
packmsg := BuildMsg(jsonstring) | |
fmt.Printf("%v\n", packmsg) | |
packmsg.Pack(&buf) | |
conn.Write(buf.Bytes()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment