func (p *TFramedTransport) Flush() error { // 确保Transport是打开的 if !p.IsOpen() { err := p.Open() if err != nil { return err } } size := p.buf.Len() buf := p.buffer[:4] binary.BigEndian.PutUint32(buf, uint32(size)) _, err := p.transport.Write(buf) if err != nil { p.Close() return thrift.NewTTransportExceptionFromError(err) } if size > 0 { if n, err := p.buf.WriteTo(p.transport); err != nil { print("Error while flushing write buffer of size ", size, " to transport, only wrote ", n, " bytes: ", err.Error(), "\n") p.Close() return thrift.NewTTransportExceptionFromError(err) } } err = p.transport.Flush() if err != nil { p.Close() } return thrift.NewTTransportExceptionFromError(err) }
func (p *TBufferedFramedTransport) Read(buf []byte) (l int, err error) { // 1. 首先读取Frame Header if p.FrameSize == 0 { p.FrameSize, err = p.readFrameHeader() if err != nil { return } } // 2. 异常处理 if p.FrameSize < len(buf) { frameSize := p.FrameSize tmp := make([]byte, p.FrameSize) l, err = p.Read(tmp) copy(buf, tmp) if err == nil { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Not enough frame size %d to read %d bytes", frameSize, len(buf))) return } } // 3. 读取剩下的数据 got, err := p.Reader.Read(buf) p.FrameSize = p.FrameSize - got //sanity check if p.FrameSize < 0 { return 0, thrift.NewTTransportException(thrift.UNKNOWN_TRANSPORT_EXCEPTION, "Negative frame size") } return got, thrift.NewTTransportExceptionFromError(err) }
// 读取Frame的完整的数据,包含 func (p *TBufferedFramedTransport) ReadFrame() (frame []byte, err error) { if p.FrameSize != 0 { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Unexpected frame size: %d", p.FrameSize)) return nil, err } var frameSize int // Reader来自transport, 中间被封装了多长 frameSize, err = p.readFrameHeader() if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Header Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Header Read Error: %s", err.Error())) } return } bytes := getSlice(frameSize, frameSize) // 什么时候会出现? // 1. 如果tcp package比较大,则容易出现package的一部分先到,另一部分随后再到 // 2. 在同一个机器上的两个进程之间出现的概率低(Time Delay小); 跨机器访问,出现概率高 var l int l, err = io.ReadFull(p.Reader, bytes) // l, err = p.Reader.Read(bytes) if l != frameSize { log.Warnf(Red("<==== ReadFrame frame size: %d, Got: %d"), frameSize, l) } if err != nil { err1, ok := err.(thrift.TTransportException) if ok { err = thrift.NewTTransportException(err1.TypeId(), fmt.Sprintf("Frame Data Read Error: %s", err1.Error())) } else { err = thrift.NewTTransportExceptionFromError( fmt.Errorf("Frame Data Read Error: %s", err.Error())) } return nil, err } return bytes, nil }
func (p *TFramedTransport) ReadByte() (c byte, err error) { // 确保Transport是打开的 if !p.IsOpen() { err = p.Open() if err != nil { return 0, err } } if p.frameSize == 0 { p.frameSize, err = p.readFrameHeader() if err != nil { p.Close() return } } if p.frameSize < 1 { p.Close() return 0, thrift.NewTTransportExceptionFromError(fmt.Errorf("Not enough frame size %d to read %d bytes", p.frameSize, 1)) } c, err = p.reader.ReadByte() if err == nil { p.frameSize-- } else { p.Close() } return }
// // 先写入数据,然后再Flush Transport // func (p *TBufferedFramedTransport) FlushBuffer(force bool) error { size := p.Buffer.Len() // 没有有效的数据,直接返回 if size == 0 { return nil } // TODO: 待优化 force = true // 1. 将p.buf的大小以BigEndian模式写入: buf中 buf := p.LenghW[:4] binary.BigEndian.PutUint32(buf, uint32(size)) // log.Printf("----> Frame Size: %d, %v\n", size, buf) // 然后transport中先写入: 长度信息 _, err := p.Writer.Write(buf) if err != nil { return thrift.NewTTransportExceptionFromError(err) } // 2. 然后继续写入p.buf中的数据 if size > 0 { var ( n int64 err error ) // 如果 err == io.ErrShortWrite, p.Writer中也有buffer, 因此可以不用考虑异常 if n, err = p.Buffer.WriteTo(p.Writer); err != nil { log.ErrorErrorf(err, "Error Flushing Expect Write: %d, but %d\n", size, n) return thrift.NewTTransportExceptionFromError(err) } if n < int64(size) { log.Printf(Red("Buffer Write Not Finished")) } } p.nbuffered++ // Buffer重新开始处理数据 p.Buffer.Reset() // Flush Buffer return p.flushTransport(force) }
func (p *TBufferedFramedTransport) Write(buf []byte) (int, error) { // 直接写入Buffer n, err := p.Buffer.Write(buf) if n != len(buf) { log.Errorf("TBufferedFramedTransport#Write Error") } return n, thrift.NewTTransportExceptionFromError(err) }
func (p *TUnixDomain) Read(buf []byte) (int, error) { if !p.IsOpen() { return 0, thrift.NewTTransportException(thrift.NOT_OPEN, "Connection not open") } p.pushDeadline(true, false) n, err := p.conn.Read(buf) return n, thrift.NewTTransportExceptionFromError(err) }
func (p *TFramedTransport) Read(buf []byte) (l int, err error) { // 确保Transport是打开的 if !p.IsOpen() { err = p.Open() if err != nil { return 0, err } } if p.frameSize == 0 { p.frameSize, err = p.readFrameHeader() if err != nil { p.Close() return } } if p.frameSize < len(buf) { frameSize := p.frameSize tmp := make([]byte, p.frameSize) l, err = p.Read(tmp) copy(buf, tmp) if err == nil { p.Close() err = thrift.NewTTransportExceptionFromError(fmt.Errorf("Not enough frame size %d to read %d bytes", frameSize, len(buf))) return } } got, err := p.reader.Read(buf) p.frameSize = p.frameSize - got //sanity check if p.frameSize < 0 { p.Close() return 0, thrift.NewTTransportException(thrift.UNKNOWN_TRANSPORT_EXCEPTION, "Negative frame size") } if err != nil { p.Close() } return got, thrift.NewTTransportExceptionFromError(err) }
func (p *TFramedTransport) Write(buf []byte) (int, error) { // 确保Transport是打开的 if !p.IsOpen() { err := p.Open() if err != nil { return 0, err } } n, err := p.buf.Write(buf) if err != nil { p.Close() } return n, thrift.NewTTransportExceptionFromError(err) }
func (p *TBufferedFramedTransport) ReadByte() (c byte, err error) { if p.FrameSize == 0 { p.FrameSize, err = p.readFrameHeader() if err != nil { return } } if p.FrameSize < 1 { return 0, thrift.NewTTransportExceptionFromError( fmt.Errorf("Not enough frame size %d to read %d bytes", p.FrameSize, 1)) } c, err = p.Reader.ReadByte() if err == nil { p.FrameSize-- } return }
func (p *TServerUnixDomain) Accept() (thrift.TTransport, error) { p.mu.RLock() interrupted := p.interrupted p.mu.RUnlock() if interrupted { return nil, errors.New("Transport Interrupted") } if p.listener == nil { return nil, thrift.NewTTransportException(thrift.NOT_OPEN, "No underlying server socket") } conn, err := p.listener.Accept() if err != nil { return nil, thrift.NewTTransportExceptionFromError(err) } return thrift.NewTSocketFromConnTimeout(conn, p.clientTimeout), nil }