func (c *Client) readLoop() {
	var err error
	var req Request
	var resp Response
	for err == nil {
		req = Request{}
		resp = Response{}
		if err = c.codec.ReadHeader(&req, &resp); err != nil {
			break
		}
		if req.Method != "" {
			if err = c.readRequest(&req); err != nil {
				log.Println("rpc2: error reading request:", err.Error())
			}
		} else {
			if err = c.readResponse(&resp); err != nil {
				log.Println("rpc2: error reading response:", err.Error())
			}
		}
	}
	c.sending.Lock()
	c.mutex.Lock()
	c.shutdown = true
	closing := c.closing
	if err == io.EOF {
		if closing {
			err = ErrShutdown
		} else {
			err = io.ErrUnexpectedEOF
		}
	}
	for _, call := range c.pending {
		call.Error = err
		call.done()
	}
	c.mutex.Unlock()
	c.sending.Unlock()
	if err != io.EOF && !closing && !c.server {
		log.Println("rpc2: client protocol error:", err)
	}
	close(c.disconnect)
}
readLoop reads messages from codec.
It reads a reqeust or a response to the previous request.
If the message is request, calls the handler function.
If the message is response, sends the reply to the associated call.
package rpc2
import (
	"errors"
	"io"
	"log"
	"reflect"
	"sync"
)
type Client struct {
	mutex      sync.Mutex  
	sending    sync.Mutex
	request    Request  
	seq        uint64
	pending    map[uint64]*Call
	closing    bool
	shutdown   bool
	server     bool
	codec      Codec
	handlers   map[string]*handler
	disconnect chan struct{}
}
func NewClient(conn io.ReadWriteCloser) *Client {
	return NewClientWithCodec(newGobCodec(conn))
}
func NewClientWithCodec(codec Codec) *Client {
	return &Client{
		codec:      codec,
		pending:    make(map[uint64]*Call),
		handlers:   make(map[string]*handler),
		disconnect: make(chan struct{}),
		seq:        1,  
	}
}
func (c *Client) Run() {
	c.readLoop()
}
func (c *Client) DisconnectNotify() chan struct{} {
	return c.disconnect
}
func (c *Client) Handle(method string, handlerFunc interface{}) {
	addHandler(c.handlers, method, handlerFunc)
}