Last active
May 13, 2019 02:37
-
-
Save SLonger/a136ffc0f5b4caa50559f1435753602c to your computer and use it in GitHub Desktop.
tcp 粘包处理 client
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 ( | |
"bufio" | |
"bytes" | |
"encoding/binary" | |
"flag" | |
"fmt" | |
"io" | |
"net" | |
"os" | |
"strconv" | |
) | |
var host = flag.String("host", "localhost", "The hostname or IP to connect to; defaults to \"localhost\".") | |
var port = flag.Int("port", 8000, "The port to connect to; defaults to 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 main() { | |
flag.Parse() | |
dest := *host + ":" + strconv.Itoa(*port) | |
fmt.Printf("Connecting to %s...\n", dest) | |
conn, err := net.Dial("tcp", dest) | |
if err != nil { | |
if _, t := err.(*net.OpError); t { | |
fmt.Println("Some problem connecting.") | |
} else { | |
fmt.Println("Unknown error: " + err.Error()) | |
} | |
os.Exit(1) | |
} | |
readConnection(conn) | |
} | |
func readConnection(conn net.Conn) { | |
scanner := bufio.NewScanner(conn) | |
// 数据的分离规则,根据协议自定义 | |
//设置分离函数 | |
split := func(data []byte, atEOF bool) (advance int, token []byte, err error) { | |
if !atEOF && bytes.Equal(data[:2], []byte("V1")) { | |
if len(data) > 10 { | |
var dataLen int64 | |
binary.Read(bytes.NewReader(data[2:10]), binary.BigEndian, &dataLen) | |
if int(dataLen)+10 <= len(data) { | |
token = data[int64(10) : int64(10)+int64(dataLen)] | |
return int(dataLen) + 10, token, nil | |
} | |
} | |
} | |
return | |
} | |
scanner.Split(split) | |
for { | |
for scanner.Scan() { | |
//fmt.Println(string(scanner.Text()) | |
fmt.Println(scanner.Bytes()) | |
} | |
if err := scanner.Err(); err != nil { | |
fmt.Printf("Invalid input: %s", err) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment