Exemple #1
0
func (p *proxy) pipe(src, dst *net.TCPConn, powerCallback common.Callback) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make([]byte, 0xffff)
	for {
		n, err := src.Read(buff)
		if err != nil {
			p.err("Read failed '%s'\n", err)
			return
		}
		b := buff[:n]
		//show output
		if islocal {
			b = getModifiedBuffer(b, powerCallback)
			n, err = dst.Write(b)
		} else {
			//write out result
			n, err = dst.Write(b)
		}
		if err != nil {
			p.err("Write failed '%s'\n", err)
			return
		}
	}
}
Exemple #2
0
func send(tcpconn *net.TCPConn, rsp *Response) (err error) {
	Len := uint32(PkgLenSize) + uint32(len(rsp.Head)) + uint32(len(rsp.Body))
	Hlen := uint16(Uint16Size) + uint16(len(rsp.Head))
	data := make([]byte, 0, int(Len)) // len:0, cap:Len; TODO(zog): cache
	buf := bytes.NewBuffer(data)      // TODO(zog): 复用
	binary.Write(buf, binary.BigEndian, Len)
	binary.Write(buf, binary.BigEndian, Hlen)
	buf.Write(rsp.Head)
	buf.Write(rsp.Body)
	if debug {
		glog.Infof("sent bytes to %s, len: %d",
			tcpconn.RemoteAddr().String(), len(buf.Bytes()))
		glog.Flush()
	}

	tcpconn.SetDeadline(time.Now().Add(100 * time.Millisecond))
	if _, err = tcpconn.Write(buf.Bytes()); err != nil {
		return err
	}

	if debug {
		glog.Infof("sent data(len:%d): %v", buf.Len(), buf.Bytes())
		glog.Flush()
	}

	return nil
}
Exemple #3
0
func listenForMoveRequests(conn *net.TCPConn) {
	listenServe := make(chan []uint8)
	easynet.TieConnToChannel(conn, listenServe)
	for data := range listenServe {
		r := new(ttypes.BotMoveRequest)
		err := json.Unmarshal(data, r)
		easynet.DieIfError(err, "JSON error")

		if r.Kill {
			fmt.Printf("Bot on %s received kill signal\n", os.Args[0])
			os.Exit(0)
		}

		fmt.Printf("Bot at %d, %d received messages: %v\n", r.YourX, r.YourY, r.Messages)
		fmt.Printf("  Sees other bots: %v\n", r.OtherBots)
		//Do something

		response := new(ttypes.BotMoveResponse)
		if r.YourY < 5 {
			response.MoveDirection = "up"
		} else if r.YourY > 5 {
			response.MoveDirection = "down"
		}
		// response.BroadcastMessage = fmt.Sprintf("'I am %v at %d, %d'", os.Args[0], r.YourX, r.YourY)
		responseString, err := json.Marshal(response)
		easynet.DieIfError(err, "JSON marshal error")
		conn.Write(responseString)
	}
}
Exemple #4
0
func sendMessage(hostName string, portNumber int, msg []byte) {
	tcpAddr, err := net.ResolveTCPAddr("tcp4", net.JoinHostPort(hostName, strconv.Itoa(portNumber)))
	checkError(err)

	var conn *net.TCPConn
	for {
		conn, err = net.DialTCP("tcp", nil, tcpAddr)
		if err != nil {
			switch e := err.(type) {
			case (*net.OpError):
				if e.Err.Error() == "connection refused" {
					return
				}
			default:
				fmt.Println(err)
			}
		} else {
			break
		}
	}

	_, err = conn.Write(msg)
	checkError(err)
	conn.Close()
	return
}
Exemple #5
0
func (hs *SimpleHandshake) WithClient(conn *Conn) error {
	var iorw *net.TCPConn = conn.IoRw

	c0c1 := make([]byte, 1537)
	conn.Logger.Info("read c0c1 from conn, size=%v", len(c0c1))
	if _, err := io.ReadFull(iorw, c0c1); err != nil {
		conn.Logger.Error("read c0c1 failed, err is %v", err)
		return err
	}
	conn.Logger.Info("read c0c1 ok")

	if c0c1[0] != 0x03 {
		conn.Logger.Error("rtmp plain required 0x03, actual is %#x", c0c1[0])
		return RtmpPlainRequired
	}
	conn.Logger.Info("check rtmp plain protocol ok")

	// use bytes buffer to write content.
	s0s1s2 := bytes.NewBuffer(make([]byte, 0, 3073))

	// plain text required.
	binary.Write(s0s1s2, binary.BigEndian, byte(0x03))
	// s1 time
	binary.Write(s0s1s2, binary.BigEndian, int32(time.Now().Unix()))
	// s1 time2 copy from c1
	if _, err := s0s1s2.Write(c0c1[1:5]); err != nil {
		conn.Logger.Error("copy c0c1 time to s0s1s2 failed, err is %v", err)
		return err
	}
	// s1 1528 random bytes
	s0s1s2Random := make([]byte, 1528)
	RandomGenerate(conn.Rand, s0s1s2Random)
	if _, err := s0s1s2.Write(s0s1s2Random); err != nil {
		conn.Logger.Error("fill s1 random bytes failed, err is %v", err)
		return err
	}
	// if c1 specified, copy c1 to s2.
	// @see: https://github.com/winlinvip/simple-rtmp-server/issues/46
	if _, err := s0s1s2.Write(c0c1[1:1537]); err != nil {
		conn.Logger.Error("copy c1 to s1 failed, err is %v", err)
		return err
	}
	conn.Logger.Info("generate s0s1s2 ok, buf=%d", s0s1s2.Len())

	if written, err := iorw.Write(s0s1s2.Bytes()); err != nil {
		conn.Logger.Error("send s0s1s2 failed, written=%d, err is %v", written, err)
		return err
	}
	conn.Logger.Info("send s0s1s2 ok")

	c2 := make([]byte, 1536)
	conn.Logger.Info("read c2 from conn, size=%v", len(c2))
	if _, err := io.ReadFull(iorw, c2); err != nil {
		conn.Logger.Error("read c2 failed, err is %v", err)
		return err
	}
	conn.Logger.Info("read c2 ok")

	return nil
}
Exemple #6
0
func pipeThenClose(src, dst *net.TCPConn, finishChannel chan bool) {
	defer func() {
		src.CloseRead()
		dst.CloseWrite()
		finishChannel <- true
	}()

	buf := asocks.GetBuffer()
	defer asocks.GiveBuffer(buf)

	for {
		src.SetReadDeadline(time.Now().Add(60 * time.Second))
		n, err := src.Read(buf)
		if n > 0 {
			data := buf[0:n]
			encodeData(data)
			if _, err := dst.Write(data); err != nil {
				break
			}
		}
		if err != nil {
			break
		}
	}
}
Exemple #7
0
func readRemoteLoop(client, remote *net.TCPConn, stopChan chan<- bool) {
	defer func() {
		stopChan <- true
	}()
	addr := client.RemoteAddr()

	for {
		var buf [4096]byte
		nr, err := remote.Read(buf[:])
		if err != nil && err != os.EOF {
			log.Printf("%v: Failed to read from the remote: %v", addr, err)
			return
		}

		start := 0
		for start < nr {
			nw, err := client.Write(buf[start:nr])
			if err != nil && err != os.EOF {
				log.Printf("%v: Failed to write to the client: %v", addr, err)
				return
			}
			start += nw
		}
	}
}
func (p *Proxy) pipe(src, dst *net.TCPConn) {
	//data direction
	islocal := src == p.lconn

	//directional copy (64k buffer)
	buff := make([]byte, 0xffff)
	for {
		n, err := src.Read(buff)
		if err != nil {
			p.err("Read failed '%s'\n", err)
			return
		}
		b := buff[:n]
		//show output
		n, err = dst.Write(b)
		if err != nil {
			p.err("Write failed '%s'\n", err)
			return
		}
		if islocal {
			p.sentBytes += uint64(n)
		} else {
			p.receivedBytes += uint64(n)
		}
	}
}
Exemple #9
0
func SendToConn(data []byte, conn *net.TCPConn, path *big.Int) {
	// making variable for combining send data
	var (
		err           tree_lib.TreeError
		path_len_data = make([]byte, 4)
		msg_len_data  = make([]byte, 4)
		path_data     = path.Bytes()
		path_len      = uint32(len(path_data))
		buf           = bytes.Buffer{}
	)

	err.From = tree_lib.FROM_SEND_TO_CONN

	binary.LittleEndian.PutUint32(path_len_data, path_len)
	binary.LittleEndian.PutUint32(msg_len_data, path_len+uint32(len(data))+uint32(4))

	buf.Write(msg_len_data)
	buf.Write(path_len_data)
	buf.Write(path_data)
	buf.Write(data)

	if conn != nil {
		_, err.Err = conn.Write(buf.Bytes())
		if !err.IsNull() {
			tree_log.Error(err.From, fmt.Sprintf("Error sending data to path [%s]", path.String()), err.Error())
		}
	}

	buf.Reset()
}
Exemple #10
0
func handleRequest(conn *net.TCPConn, request *vmessio.VMessRequest, input <-chan []byte, finish chan<- bool) {
	defer close(finish)
	encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn)
	if err != nil {
		log.Error("VMessOut: Failed to create encrypt writer: %v", err)
		return
	}

	buffer, err := request.ToBytes(v2hash.NewTimeHash(v2hash.HMACHash{}), v2math.GenerateRandomInt64InRange)
	if err != nil {
		log.Error("VMessOut: Failed to serialize VMess request: %v", err)
		return
	}

	// Send first packet of payload together with request, in favor of small requests.
	payload, open := <-input
	if open {
		encryptRequestWriter.Crypt(payload)
		buffer = append(buffer, payload...)

		_, err = conn.Write(buffer)
		if err != nil {
			log.Error("VMessOut: Failed to write VMess request: %v", err)
			return
		}

		v2net.ChanToWriter(encryptRequestWriter, input)
	}
	return
}
Exemple #11
0
func session(conn *net.TCPConn) {
	fmt.Println("here")
	var buf [2048]byte
	code := 0
	for {
		t := time.Now().Add(time.Millisecond * 100)
		conn.SetReadDeadline(t)
		n, err := conn.Read(buf[:])
		e, ok := err.(net.Error)

		if err != nil && ok && !e.Timeout() {
			fmt.Println(err)
			break
		}

		if n > 0 {
			process(conn, buf[:n])
		} else {
			msg := fmt.Sprintf("%v", code)
			code++
			conn.Write([]byte(msg))
		}
	}
	fmt.Println("session ended")
}
Exemple #12
0
func tcpWorker(conn *net.TCPConn, server string) {
	go handleReader(conn, server)
	pkg := &ProtoPkg{
		Header: new(ProtoHeader),
		Body:   []byte("I am a good boy"),
	}
	pkg.Header.Version = Version
	pkg.Header.Cmd = 111
	//	fmt.Println(pkg, pkgData)
	for {
		for i := 0; i < 10; i++ {
			seq = atomic.AddUint32(&seq, 1)
			pkg.Header.Seq = seq
			seqInfo := &SeqInfo{
				t:      time.Now(),
				server: server,
			}
			seqMap[seq] = seqInfo
			pkgData := Pack(pkg)
			conn.Write(pkgData)
		}
		checkTimeout()
		time.Sleep(100 * time.Millisecond)
	}
}
Exemple #13
0
func writeLoop(conn *net.TCPConn) {
	in := bufio.NewReader(os.Stdin)
	for {
		line, _ := in.ReadString('\n')
		conn.Write(strings.Bytes(line))
	}
}
Exemple #14
0
func readloop(conn *net.TCPConn, clist *[]ChanPair, controlc chan chan string) {
	output := make(chan string, 2048)
	input := make(chan string, 2048)
	controlc <- output
	controlc <- input
	address := conn.RemoteAddr()
	player := parsing.NewPlayer(address.String())
	for {
		b := make([]byte, 4096)
		n, err := conn.Read(b[:])
		data := b[:n]
		if err != nil {
			fmt.Println(err)
		}

		select {
		case str := <-input:
			conn.Write([]uint8(str))
		default:
		}

		if len(string(data)) == 0 {
			fmt.Println("PARTING:", address.String())
			conn.Close()
			return
		}
		conn.Write(parsing.Parse(player, string(data), output))
	}
}
Exemple #15
0
// Handles connections to a service and calls the handler specified in RunService().
func handleServiceConnection(connection *net.TCPConn, handler ServiceHandler) error {
	servicecall := ServiceCall{}
	buffer := make([]byte, PACKET_SIZE)

	defer connection.Close()

	length, err := connection.Read(buffer)
	if err != nil {
		return err
	}
	err = json.Unmarshal(buffer[:length], &servicecall)
	if err != nil {
		return err
	}

	ret := handler(&servicecall)

	bytes, err := json.Marshal(ServiceResult{ret})
	if err != nil {
		return err
	}
	_, err = connection.Write(bytes)
	if err != nil {
		return err
	}

	return nil
}
Exemple #16
0
func serve(con *net.TCPConn) {

	defer con.Close()

	if *verbose {
		fmt.Fprintf(os.Stdout, "serving %s\n", con.RemoteAddr().String())
	}

	for {

		line, err := readUntilCrLf(con)

		if err != nil {
			// TODO : pass error message
			con.Write([]byte("\"internal error\"\r\n"))
			continue
		}

		tokens := strings.Split(string(line), " ", -1)

		command := tokens[0]

		if command == "quit" {
			writeJson(con, "bye.")
			break
		}

		f, ok := commands[command]
		if ok {
			f(con, tokens[1:])
		} else {
			writeJson(con, fmt.Sprintf("unknown command '%s'", command))
		}
	}
}
Exemple #17
0
func RunTelnet(ws *websocket.Conn, conn *net.TCPConn) {
	fmt.Println("Running telnet")
	go ReadSocket(ws, conn)

	// Read websocket and write to socket.
	crlf := []byte{13, 10}
	var msg string
	for {
		err := websocket.Message.Receive(ws, &msg)
		if err != nil {
			_ = conn.Close()
			break
		}
		_, err = conn.Write([]byte(msg))
		if err != nil {
			break
		}
		fmt.Println("Sent message to host:", msg)
		// Send \r\n (as HTTP protocol requires)
		_, err = conn.Write(crlf)
		if err != nil {
			break
		}
	}
	fmt.Println("RunTelnet exit")
}
Exemple #18
0
func forward(source *net.TCPConn, dest *net.TCPConn) {
	defer func() {
		dest.Close()
	}()

	bufsz := 1 << 12
	cache := make([]byte, bufsz)
	for {
		// pump from source
		n, err1 := source.Read(cache)

		// pour into dest
		c := 0
		var err2 error
		for c < n {
			i, err2 := dest.Write(cache[c:n])
			if err2 != nil {
				break
			}
			c += i
		}

		if err1 != nil || err2 != nil {
			break
		}
	}
}
Exemple #19
0
func write(conn *net.TCPConn) {

	n := protocol.Mode(5)
	reg := &protocol.WMessage{
		MsgType:   proto.String("sendMsg"),
		MsgTypeId: proto.Int32(8),
		UserInfo: &protocol.User{
			Username: proto.String("jim"),
			//Password: proto.String("123456"),
		},
		SendMsg: &protocol.SendMessage{
			Receiver: proto.String("zhang"),
			MsgType:  &n,
			Msg:      proto.String("吃了吗?"),
		},
	}
	buf, err := proto.Marshal(reg)
	if err != nil {
		fmt.Println("failed: %s\n", err)
		return
	}
	fmt.Println("buf: ", len(buf))
	length := len(buf)
	buffer := append(common.IntToBytes(length), buf...)
	conn.Write(buffer)
	//return buffer
	//conn.Write(common.IntToBytes(length))
}
Exemple #20
0
func keepAlive(conn *net.TCPConn) {
	for {
		time.Sleep(60 * time.Second)
		enq := EnquireLink(1)
		conn.Write(enq.Pack())
	}
}
Exemple #21
0
func (this *DelayProxy) tcpForward(src *net.TCPConn, dest *net.TCPConn, finishedChan chan int) {
	var err error
	var n int
	var buffer = make([]byte, CHUNK_SIZE)

	for {
		n, err = src.Read(buffer)
		if n < 1 {
			break
		}

		if err != nil {
			Logf("%s: read error: %d %s\n", this.id, n, err)
			break
		}

		Sleep(this.transferDelay)

		n, err = dest.Write(buffer[0:n])
		if n < 1 {
			break
		}

		if err != nil {
			Logf("%s: write error: %d %s\n", this.id, n, err)
			break
		}
	}

	finishedChan <- 1
}
Exemple #22
0
//
// A TCP 'echo' example.
// Demonstrates using a timeout, and a 'graceful' shutdown if one occurs.
// 'Tested' using 'telnet localhost 45678'
//
func runReads(tcpConn *net.TCPConn) bool {
	br := bufio.NewReader(tcpConn)
	for {
		// Set a timeout value, which needs to be set before each and every read.
		d := time.Duration(30 * 1e9) // 30 seconds
		w := time.Now()              // from now
		w = w.Add(d)
		tcpConn.SetReadDeadline(w) // Set the deadline
		//
		buffer, err := br.ReadBytes('\n') // '\n' is delimiter
		// If the read times out, this prints something like:
		// Error = read tcp 127.0.0.1:57609: resource temporarily unavailable
		if err != nil {
			fmt.Printf("Error = %v\n", err)
			return false
			// panic("wtf04")
		}
		//
		fmt.Printf("Bytes Read: %d\n", len(buffer))
		var data = string(buffer)
		fmt.Printf("Data Read: |%q|\n", data)

		// This is now an 'echo' example.
		out := "echo: " + data
		tcpConn.Write([]byte(out))

		// The \r in this data from telnet is a bit surprising ...
		if data == "quit\r\n" {
			fmt.Println("Breaking....")
			break
		}
	}
	return true
}
Exemple #23
0
func handleRequest(conn *net.TCPConn, request *protocol.VMessRequest, input <-chan []byte, finish *sync.Mutex) {
	defer finish.Unlock()
	encryptRequestWriter, err := v2io.NewAesEncryptWriter(request.RequestKey[:], request.RequestIV[:], conn)
	if err != nil {
		log.Error("VMessOut: Failed to create encrypt writer: %v", err)
		return
	}

	buffer := make([]byte, 0, 2*1024)
	buffer, err = request.ToBytes(user.NewTimeHash(user.HMACHash{}), user.GenerateRandomInt64InRange, buffer)
	if err != nil {
		log.Error("VMessOut: Failed to serialize VMess request: %v", err)
		return
	}

	// Send first packet of payload together with request, in favor of small requests.
	payload, open := <-input
	if open {
		encryptRequestWriter.Crypt(payload)
		buffer = append(buffer, payload...)

		_, err = conn.Write(buffer)
		if err != nil {
			log.Error("VMessOut: Failed to write VMess request: %v", err)
			return
		}

		v2net.ChanToWriter(encryptRequestWriter, input)
	}
	return
}
Exemple #24
0
// NewClient returns new TCP client connection.
func NewClient(md *meta.Data, serverAddress string, sockerPort, providerPort int) (client *Client, err error) {
	var tcpAddr *net.TCPAddr
	tcpAddr, err = net.ResolveTCPAddr("tcp4", serverAddress)
	if err != nil {
		return
	}

	var tcpConn *net.TCPConn
	tcpConn, err = net.DialTCP("tcp", nil, tcpAddr)
	if err != nil {
		return
	}

	tcpConn.Write(append([]byte(md.UserID+"::"+strconv.Itoa(sockerPort)+"::"+strconv.Itoa(providerPort)), '\n'))

	client = &Client{
		TCPConn: tcpConn,
		close:   make(chan bool),
		ackChan: make(chan bool),
		reader:  bufio.NewReader(tcpConn),
		md:      md,
	}

	return
}
Exemple #25
0
func InitClient(conn *net.TCPConn, devid string) *Client {
	client := &Client{
		devId:           devid,
		ctrl:            make(chan bool),
		MsgOut:          make(chan *Pack, 100),
		WaitingChannels: make(map[uint32]chan *Message),
		NextSeqId:       1,
		LastAlive:       time.Now(),
	}
	DevMap.Set(devid, client)

	go func() {
		log.Tracef("start send routine for %s", conn.RemoteAddr().String())
		for {
			select {
			case pack := <-client.MsgOut:
				seqid := pack.client.NextSeqId
				pack.msg.Header.Seq = seqid
				b, _ := pack.msg.Header.Serialize()
				conn.Write(b)
				conn.Write(pack.msg.Data)
				log.Infof("send msg ok, (%s)", string(pack.msg.Data))
				pack.client.NextSeqId += 1
				// add reply channel
				if pack.reply != nil {
					pack.client.WaitingChannels[seqid] = pack.reply
				}
			case <-client.ctrl:
				log.Tracef("leave send routine for %s", conn.RemoteAddr().String())
				return
			}
		}
	}()
	return client
}
Exemple #26
0
func (consumer *BrokerConsumer) tryConnect(conn *net.TCPConn, tp *TopicPartition) (err error, reader *ByteBuffer) {
	var errCode int
	request := consumer.broker.EncodeConsumeRequest()
	//log.Println("offset=", tp.Offset, " ", tp.MaxSize, " ", tp.Topic, " ", tp.Partition, "  \n\t", string(request), request)
	_, err = conn.Write(request)
	if err != nil {
		if err = consumer.handleConnError(err, conn); err != nil {
			return err, nil
		}
	}

	reader = consumer.broker.readResponse(conn)
	err, errCode = reader.ReadHeader()
	if err != nil && errCode == 1 {
		log.Println("Bad Offset id, resetting?")
		// Error Code 1 means bad offsetid, we shold get a good offset, and reconnect!
		offsetVal := GetOffset(consumer.broker.hostname, tp)
		if offsetVal > 0 {
			// RECONNECT!
			log.Println("RECONNECTING !!! ", offsetVal)
			tp.Offset = offsetVal
			if err, reader = consumer.tryConnect(conn, tp); err != nil {
				return err, nil
			}
		} else {
			return err, nil
		}

	} else if err != nil {
		//log.Println("offset=", tp.Offset, " ", tp.MaxSize, " ", err.Error(), " ", request, " ", tp.Topic, " ", tp.Partition, "  \n\t", string(request))
		return err, nil
	}
	return
}
Exemple #27
0
// 分发请求;响应请求命令
func (self *AgentSvr) dispatchRequst(conn *net.TCPConn, req *Request) {
	defer func() {
		if err := recover(); err != nil {
			Error("handle agent connection:%v failed:%v", conn.RemoteAddr(), err)
		}
	}()
	cb, ok := self.handers[req.Method]
	if ok {
		ud := cb[0]
		handler := cb[1].(AgentHandler)
		var resp Response
		resp.Id = req.Id
		if result, err := handler(ud, req.Params); err != nil {
			resp.Error = err
		} else {
			resp.Result = result
		}
		body, err := json.Marshal(resp)
		if err != nil {
			Panic("marshal response conn:%v, failed:%v", conn.RemoteAddr(), err)
		}

		length := uint32(len(body))
		buf := bytes.NewBuffer(nil)
		binary.Write(buf, binary.BigEndian, length)
		buf.Write(body)
		chunk := buf.Bytes()
		if _, err = conn.Write(chunk); err != nil {
			Panic("write response conn:%v, failed:%v", conn.RemoteAddr(), err)
		}
	} else {
		Error("unknown request:%v", req)
	}
}
Exemple #28
0
func handleConnection(conn *net.TCPConn, no_delay int, packet_bytes int) {
	defer conn.Close()
	fmt.Println("handle connection", conn)

	if no_delay == 0 {
		if err := conn.SetNoDelay(false); err != nil {
			fmt.Println("set no delay to false failed.")
			return
		}
		fmt.Println("set no delay to false ok.")
	}

	/*SO_SNDBUF := 16384
	  if err := conn.SetWriteBuffer(SO_SNDBUF); err != nil {
	      fmt.Println("set send SO_SNDBUF failed.")
	      return
	  }
	  fmt.Println("set send SO_SNDBUF to", SO_SNDBUF, "ok.")*/

	b := make([]byte, packet_bytes)
	fmt.Println("write", len(b), "bytes to conn")

	for {
		n, err := conn.Write(b)
		if err != nil {
			fmt.Println("write data error, n is", n, "and err is", err)
			break
		}
	}
}
Exemple #29
0
func write(conn *net.TCPConn, cmd string) {
	cmd = fmt.Sprintf("%s\n", cmd)
	_, err := conn.Write([]byte(cmd))
	if err != nil {
		panic(err)
	}
}
Exemple #30
0
// Write 3 message in one package
func testMutipleMessage(client *net.TCPConn, buf *bytes.Buffer) error {
	data := bytes.Repeat(buf.Bytes(), 3)
	if _, err := client.Write(data); err != nil {
		return err
	}
	return EqualRead(client, data)
}