func (c Conn) Receive() (*Reply, error) {
	reply := new(Reply)
	lineType, replyLine, err := c.readLine()
	if err != nil {
		return reply, nil
	}
	if lineType != endLine {
		if reply.Lines == nil {
			reply.Lines = make([]ReplyLine, 0, 1)
		} else {
			reply.Lines = reply.Lines[:0]
		}
	}
	for err == nil && lineType != endLine {
		reply.Lines = append(reply.Lines, *replyLine)
		lineType, replyLine, err = c.readLine()
		if err != nil {
			return reply, err
		}
	}
	reply.Status = replyLine.Status
	reply.Text = replyLine.Text
	return reply, nil
}
Receive reads and returns a single reply from the Tor server.
It makes no distinction between synchronous and asynchronous replies.
package control
import (
	"errors"
	"strconv"
	"strings"
)
type Reply struct {
	Status int          
	Text   string       
	Lines  []ReplyLine  
}
func (r Reply) String() string {
	s := strconv.Itoa(r.Status) + " " + r.Text
	for _, line := range r.Lines {
		s = s + "\n" + line.String()
	}
	return s
}
const (
	StatusOK                   = 250
	StatusOperationUnnecessary = 251
	StatusResourceExhausted = 451
	StatusProtocolSyntaxError = 500
	StatusUnrecognizedCommand    = 510
	StatusUnimplementedCommand   = 511
	StatusArgumentSyntaxError    = 512
	StatusUnrecognizedArgument   = 513
	StatusAuthenticationRequired = 514
	StatusBadAuthentication      = 515
	StatusUnspecifiedError   = 550
	StatusInternalError      = 551
	StatusUnrecognizedEntity = 552
	StatusInvalidConfigurationValue = 553
	StatusInvalidDescriptor         = 554
	StatusUnmanagedEntity = 555
	StatusAsyncEventNotification = 650
)
func (r Reply) IsAsync() bool {
	return r.Status == 650
}
func (r Reply) IsSync() bool {
	return r.Status != 650
}
type ReplyLine struct {
	Status int
	Text   string
	Data string
}
func (rl ReplyLine) String() string {
	s := strconv.Itoa(rl.Status) + " " + rl.Text + " " + rl.Data
	return s
}
const (
	midLine = iota
	dataLine
	endLine
)
func (c Conn) readLine() (lineType int, rl *ReplyLine, err error) {
	line, err := c.text.ReadLine()
	if err != nil {
		return
	}
	status, lineType, text, err := parseLine(line)
	if err != nil {
		return lineType, nil, err
	}
	rl = new(ReplyLine)
	rl.Status = status
	rl.Text = text
	if lineType == dataLine {
		data, err := c.readData()
		rl.Data = data
		if err != nil {
			return lineType, nil, err
		}
	}
	return
}
func parseLine(line string) (status, lineType int, text string, err error) {
	if len(line) < 4 || line[3] != ' ' && line[3] != '-' && line[3] != '+' {
		err = errors.New("protocol error: : " + line)
		return
	}
	switch line[3] {
	case '-':
		lineType = midLine
	case ' ':
		lineType = endLine
	case '+':
		lineType = dataLine
	}
	status, err = strconv.Atoi(line[0:3])
	if err != nil || status < 100 {
		err = errors.New("protocol errors: invalid status code: " + line)
		return
	}
	text = line[4:]
	return
}
func (c Conn) readData() (string, error) {
	buf, err := c.text.ReadDotBytes()
	if err != nil {
		return "", err
	}
	return string(buf), nil
}