A TCP Server Framework with graceful shutdown, custom protocol.
Clone or download
Latest commit ddad367 Jan 15, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
example upgrade Jan 15, 2019
.gitignore Initial commit Mar 31, 2016
.travis.yml modify travis script May 14, 2018
LICENSE Initial commit Mar 31, 2016
README.md Merge branch 'master' of https://github.com/xfxdev/xtcp May 12, 2018
xconn.go upgrade Jan 15, 2019
xserver.go upgrade Jan 15, 2019
xtcp.go upgrade Jan 15, 2019



A TCP Server Framework with graceful shutdown,custom protocol.

Build Status Go Report Card GoDoc


go get github.com/xfxdev/xlog // xtcp use xlog inner.
go get github.com/xfxdev/xtcp


define your protocol format:

Before create server and client, you need define the protocol format first.

// Packet is the unit of data.
type Packet interface {

// Protocol use to pack/unpack Packet.
type Protocol interface {
	// return the size need for pack the Packet.
	PackSize(p Packet) int
	// PackTo pack the Packet to w.
	// The return value n is the number of bytes written;
	// Any error encountered during the write is also returned.
	PackTo(p Packet, w io.Writer) (int, error)
	// Pack pack the Packet to new created buf.
	Pack(p Packet) ([]byte, error)
	// try to unpack the buf to Packet. If return len > 0, then buf[:len] will be discard.
	// The following return conditions must be implement:
	// (nil, 0, nil) : buf size not enough for unpack one Packet.
	// (nil, len, err) : buf size enough but error encountered.
	// (p, len, nil) : unpack succeed.
	Unpack(buf []byte) (Packet, int, error)

provide event handler:

In xtcp, there are some events to notify the state of net conn, you can handle them according your need:

const (
	// EventAccept mean server accept a new connect.
	EventAccept EventType = iota
	// EventConnected mean client connected to a server.
	// EventRecv mean conn recv a packet.
	// EventClosed mean conn is closed.

To handle the event, just implement the OnEvent interface.

// Handler is the event callback.
// p will be nil when event is EventAccept/EventConnected/EventClosed
type Handler interface {
	OnEvent(et EventType, c *Conn, p Packet)

create server:

// 1. create protocol and handler.
// ...

// 2. create opts.
opts := xtcp.NewOpts(handler, protocol)

// 3. create server.
server := xtcp.NewServer(opts)

// 4. start.
go server.ListenAndServe("addr")

create client:

// 1. create protocol and handler.
// ...

// 2. create opts.
opts := xtcp.NewOpts(handler, protocol)

// 3. create client.
client := NewConn(opts)

// 4. start
go client.DialAndServe("addr")

send and recv packet.

To send data, just call the 'Send' function of Conn. You can safe call it in any goroutines.

func (c *Conn) Send(buf []byte) error

To recv a packet, implement your handler function:

func (h *myhandler) OnEvent(et EventType, c *Conn, p Packet) {
	switch et {
		case EventRecv:


xtcp have three stop modes, stop gracefully mean conn will stop until all cached data sended.

// StopMode define the stop mode of server and conn.
type StopMode uint8

const (
	// StopImmediately mean stop directly, the cached data maybe will not send.
	StopImmediately StopMode = iota
	// StopGracefullyButNotWait stop and flush cached data.
	// StopGracefullyAndWait stop and block until cached data sended.


The example define a protocol format which use protobuf inner. You can see how to define the protocol and how to create server and client.