github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/connection_windows.go (about) 1 // +build windows 2 3 package net 4 5 import ( 6 nt "net" 7 8 "github.com/angenalZZZ/gofunc/net/pool/bytebuffer" 9 prb "github.com/angenalZZZ/gofunc/net/pool/ringbuffer" 10 "github.com/angenalZZZ/gofunc/net/ringbuffer" 11 ) 12 13 type stderr struct { 14 c *stdConn 15 err error 16 } 17 18 type wakeReq struct { 19 c *stdConn 20 } 21 22 type tcpIn struct { 23 c *stdConn 24 in *bytebuffer.ByteBuffer 25 } 26 27 type udpIn struct { 28 c *stdConn 29 } 30 31 type stdConn struct { 32 ctx interface{} // user-defined context 33 conn nt.Conn // original connection 34 loop *eventloop // owner event-loop 35 buffer *bytebuffer.ByteBuffer // reuse memory of inbound data as a temporary buffer 36 codec ICodec // codec for TCP 37 localAddr nt.Addr // local server addr 38 remoteAddr nt.Addr // remote peer addr 39 byteBuffer *bytebuffer.ByteBuffer // bytes buffer for buffering current packet and data in ring-buffer 40 inboundBuffer *ringbuffer.RingBuffer // buffer for data from client 41 } 42 43 func newTCPConn(conn nt.Conn, el *eventloop) *stdConn { 44 return &stdConn{ 45 conn: conn, 46 loop: el, 47 codec: el.codec, 48 inboundBuffer: prb.Get(), 49 } 50 } 51 52 func (c *stdConn) releaseTCP() { 53 c.ctx = nil 54 c.localAddr = nil 55 c.remoteAddr = nil 56 prb.Put(c.inboundBuffer) 57 c.inboundBuffer = nil 58 bytebuffer.Put(c.buffer) 59 c.buffer = nil 60 } 61 62 func newUDPConn(el *eventloop, localAddr, remoteAddr nt.Addr, buf *bytebuffer.ByteBuffer) *stdConn { 63 return &stdConn{ 64 loop: el, 65 localAddr: localAddr, 66 remoteAddr: remoteAddr, 67 buffer: buf, 68 } 69 } 70 71 func (c *stdConn) releaseUDP() { 72 c.ctx = nil 73 c.localAddr = nil 74 bytebuffer.Put(c.buffer) 75 c.buffer = nil 76 } 77 78 func (c *stdConn) read() ([]byte, error) { 79 return c.codec.Decode(c) 80 } 81 82 func (c *stdConn) check() { 83 if c.inboundBuffer == nil { 84 c.inboundBuffer = prb.Get() 85 } 86 } 87 88 // ================================= Public APIs ================================= 89 90 func (c *stdConn) Read() []byte { 91 c.check() 92 if c.inboundBuffer.IsEmpty() { 93 return c.buffer.Bytes() 94 } 95 c.byteBuffer = c.inboundBuffer.WithByteBuffer(c.buffer.Bytes()) 96 return c.byteBuffer.Bytes() 97 } 98 99 func (c *stdConn) ResetBuffer() { 100 c.check() 101 c.buffer.Reset() 102 c.inboundBuffer.Reset() 103 bytebuffer.Put(c.byteBuffer) 104 c.byteBuffer = nil 105 } 106 107 func (c *stdConn) ReadN(n int) (size int, buf []byte) { 108 c.check() 109 inBufferLen := c.inboundBuffer.Length() 110 tempBufferLen := c.buffer.Len() 111 if totalLen := inBufferLen + tempBufferLen; totalLen < n || n <= 0 { 112 n = totalLen 113 } 114 size = n 115 if c.inboundBuffer.IsEmpty() { 116 buf = c.buffer.B[:n] 117 return 118 } 119 head, tail := c.inboundBuffer.LazyRead(n) 120 c.byteBuffer = bytebuffer.Get() 121 _, _ = c.byteBuffer.Write(head) 122 _, _ = c.byteBuffer.Write(tail) 123 if inBufferLen >= n { 124 buf = c.byteBuffer.Bytes() 125 return 126 } 127 128 restSize := n - inBufferLen 129 _, _ = c.byteBuffer.Write(c.buffer.B[:restSize]) 130 buf = c.byteBuffer.Bytes() 131 return 132 } 133 134 func (c *stdConn) ShiftN(n int) (size int) { 135 c.check() 136 inBufferLen := c.inboundBuffer.Length() 137 tempBufferLen := c.buffer.Len() 138 if inBufferLen+tempBufferLen < n || n <= 0 { 139 c.ResetBuffer() 140 size = inBufferLen + tempBufferLen 141 return 142 } 143 size = n 144 if c.inboundBuffer.IsEmpty() { 145 c.buffer.B = c.buffer.B[n:] 146 return 147 } 148 149 bytebuffer.Put(c.byteBuffer) 150 c.byteBuffer = nil 151 152 if inBufferLen >= n { 153 c.inboundBuffer.Shift(n) 154 return 155 } 156 c.inboundBuffer.Reset() 157 158 restSize := n - inBufferLen 159 c.buffer.B = c.buffer.B[restSize:] 160 return 161 } 162 163 func (c *stdConn) BufferLength() int { 164 c.check() 165 return c.inboundBuffer.Length() + c.buffer.Len() 166 } 167 168 func (c *stdConn) AsyncWrite(buf []byte) (err error) { 169 var encodedBuf []byte 170 if encodedBuf, err = c.codec.Encode(c, buf); err == nil { 171 c.loop.ch <- func() error { 172 _, _ = c.conn.Write(encodedBuf) 173 return nil 174 } 175 } 176 return 177 } 178 179 func (c *stdConn) SendTo(buf []byte) (err error) { 180 _, err = c.loop.svr.ln.pconn.WriteTo(buf, c.remoteAddr) 181 return 182 } 183 184 func (c *stdConn) Wake() error { 185 c.loop.ch <- wakeReq{c} 186 return nil 187 } 188 189 func (c *stdConn) Close() error { 190 c.loop.ch <- func() error { 191 return c.loop.loopCloseConn(c) 192 } 193 return nil 194 } 195 196 func (c *stdConn) Context() interface{} { return c.ctx } 197 func (c *stdConn) SetContext(ctx interface{}) { c.ctx = ctx } 198 func (c *stdConn) LocalAddr() nt.Addr { return c.localAddr } 199 func (c *stdConn) RemoteAddr() nt.Addr { return c.remoteAddr }