func writer(conn net.Conn, outbox chan []byte) { defer func() { conn.Close() clearOutbox(outbox) //incase reader is blocked }() b := bytes.NewBuffer(nil) for { select { case msg, ok := <-outbox: if !ok { return } b.Write(msg) for n := len(outbox); n > 0; n-- { b.Write(<-outbox) } conn.SetWriteDeadline(time.Now().Add(5 * time.Second)) _, err := conn.Write(b.Bytes()) if err != nil { return } b.Reset() } } }
func serveSPDY(conn net.Conn, srv *http.Server) { defer func() { if v := recover(); v != nil { const size = 4096 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] log.Printf("panic serving %v: %v\n%s", conn.RemoteAddr(), v, buf) } }() tlsConn, ok := conn.(*tls.Conn) if !ok { // Only allow TLS connections. return } if d := srv.ReadTimeout; d != 0 { conn.SetReadDeadline(time.Now().Add(d)) } if d := srv.WriteTimeout; d != 0 { conn.SetWriteDeadline(time.Now().Add(d)) } if err := tlsConn.Handshake(); err != nil { return } tlsState := new(tls.ConnectionState) *tlsState = tlsConn.ConnectionState() proto := tlsState.NegotiatedProtocol if fn := srv.TLSNextProto[proto]; fn != nil { fn(srv, tlsConn, nil) } return }
func copyBytes(dst, src net.Conn, wg *sync.WaitGroup, writeDeadline, readDeadline time.Duration) { defer wg.Done() n, err := io.Copy(dst, src) if err != nil { log.Errorf("proxy i/o error: %v", err) } if cr, ok := src.(*net.TCPConn); ok { cr.CloseRead() } else { // For TLS connections. wto := time.Now().Add(writeDeadline) src.SetWriteDeadline(wto) } if cw, ok := dst.(*net.TCPConn); ok { cw.CloseWrite() } else { // For TLS connections. rto := time.Now().Add(readDeadline) dst.SetReadDeadline(rto) } log.Debugf("proxy copied %d bytes %s -> %s", n, src.RemoteAddr(), dst.RemoteAddr()) }
func (s *Server) updateWriteDeadline(c net.Conn, ctx *RequestCtx, lastDeadlineTime time.Time) time.Time { writeTimeout := s.WriteTimeout if s.MaxKeepaliveDuration > 0 { connTimeout := s.MaxKeepaliveDuration - time.Since(ctx.connTime) if connTimeout <= 0 { // MaxKeepAliveDuration exceeded, but let's try sending response anyway // in 100ms with 'Connection: close' header. ctx.SetConnectionClose() connTimeout = 100 * time.Millisecond } if connTimeout < writeTimeout { writeTimeout = connTimeout } } // Optimization: update write deadline only if more than 25% // of the last write deadline exceeded. // See https://github.com/golang/go/issues/15133 for details. currentTime := time.Now() if currentTime.Sub(lastDeadlineTime) > (writeTimeout >> 2) { if err := c.SetWriteDeadline(currentTime.Add(writeTimeout)); err != nil { panic(fmt.Sprintf("BUG: error in SetWriteDeadline(%s): %s", writeTimeout, err)) } lastDeadlineTime = currentTime } return lastDeadlineTime }
func createPeerWriter(conn net.Conn) (chan<- []byte, <-chan error) { msgChan := make(chan []byte) errChan := make(chan error) go func() { defer log.V(3).Infof("WINSTON: Peer writer goroutine exited\n") defer close(errChan) // msgChan should be closed by the caller for msg := range msgChan { // Set a deadline for sending the next message and refresh it before each message conn.SetWriteDeadline(time.Now().Add(30 * time.Second)) err := netWriteUint32(conn, uint32(len(msg))) if err != nil { errChan <- fmt.Errorf("Could not send byte of new message: '%s'", err) break } _, err = conn.Write(msg) if err != nil { errChan <- fmt.Errorf("Could not send a message: '%s'", err) break } } }() return msgChan, errChan }
// poll sends a packet and wait for a response. Both operations can timeout, they're retried up to retries times. func poll(conn net.Conn, toSend []byte, respondBuffer []byte, retries int, timeout time.Duration) (int, error) { var err error for i := 0; i < retries+1; i++ { deadline := time.Now().Add(timeout) if err = conn.SetWriteDeadline(deadline); err != nil { log.Printf("Couldn't set write deadline. Retrying. Retry %d/%d\n", i, retries) continue } if _, err = conn.Write(toSend); err != nil { log.Printf("Couldn't write. Retrying. Retry %d/%d\n", i, retries) continue } deadline = time.Now().Add(timeout) if err = conn.SetReadDeadline(deadline); err != nil { log.Printf("Couldn't set read deadline. Retrying. Retry %d/%d\n", i, retries) continue } numRead := 0 if numRead, err = conn.Read(respondBuffer); err != nil { log.Printf("Couldn't read. Retrying. Retry %d/%d\n", i, retries) continue } return numRead, nil } return 0, err }
func copyContent(from net.Conn, to net.Conn, complete chan bool, done chan bool, otherDone chan bool) { var err error = nil var bytes []byte = make([]byte, 256) var read int = 0 for { select { // If we received a done message from the other goroutine, we exit. case <-otherDone: complete <- true return default: // Read data from the source connection. from.SetReadDeadline(time.Now().Add(time.Second * 5)) read, err = from.Read(bytes) // If any errors occured, write to complete as we are done (one of the // connections closed.) if err != nil { complete <- true done <- true return } // Write data to the destination. to.SetWriteDeadline(time.Now().Add(time.Second * 5)) _, err = to.Write(bytes[:read]) // Same error checking. if err != nil { complete <- true done <- true return } } } }
// testRacyWrite tests that it is safe to mutate the input Write buffer // immediately after cancelation has occurred. func testRacyWrite(t *testing.T, c1, c2 net.Conn) { go chunkedCopy(ioutil.Discard, c2) var wg sync.WaitGroup defer wg.Wait() c1.SetWriteDeadline(time.Now().Add(time.Millisecond)) for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() b1 := make([]byte, 1024) b2 := make([]byte, 1024) for j := 0; j < 100; j++ { _, err := c1.Write(b1) copy(b1, b2) // Mutate b1 to trigger potential race if err != nil { checkForTimeoutError(t, err) c1.SetWriteDeadline(time.Now().Add(time.Millisecond)) } } }() } }
func (service *StreamService) serve(conn net.Conn) { var data []byte var err error for { if service.readTimeout != nil { err = conn.SetReadDeadline(time.Now().Add(service.readTimeout.(time.Duration))) } if err == nil { data, err = receiveDataOverStream(conn) } if err == nil { data = service.Handle(data, &StreamContext{BaseContext: NewBaseContext(), Conn: conn}) if service.writeTimeout != nil { err = conn.SetWriteDeadline(time.Now().Add(service.writeTimeout.(time.Duration))) } if err == nil { err = sendDataOverStream(conn, data) } } if err != nil { conn.Close() break } } }
// copy Content two-way func pass(from net.Conn, to net.Conn, complete chan bool, oneSide chan bool, otherSide chan bool) { var err error var read int bytes := make([]byte, 256) for { select { case <-otherSide: complete <- true return default: from.SetReadDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second)) read, err = from.Read(bytes) if err != nil { complete <- true oneSide <- true return } to.SetWriteDeadline(time.Now().Add(time.Duration(pConfig.Timeout) * time.Second)) _, err = to.Write(bytes[:read]) if err != nil { complete <- true oneSide <- true return } } } }
func serveSPDY(conn net.Conn, srv *http.Server) { defer common.Recover() tlsConn, ok := conn.(*tls.Conn) if !ok { // Only allow TLS connections. return } if d := srv.ReadTimeout; d != 0 { conn.SetReadDeadline(time.Now().Add(d)) } if d := srv.WriteTimeout; d != 0 { conn.SetWriteDeadline(time.Now().Add(d)) } if err := tlsConn.Handshake(); err != nil { return } tlsState := new(tls.ConnectionState) *tlsState = tlsConn.ConnectionState() proto := tlsState.NegotiatedProtocol if fn := srv.TLSNextProto[proto]; fn != nil { fn(srv, tlsConn, nil) } return }
func (s *session) proxy(c1, c2 net.Conn) error { if debug { log.Println("Proxy", c1.RemoteAddr(), "->", c2.RemoteAddr()) } atomic.AddInt64(&numProxies, 1) defer atomic.AddInt64(&numProxies, -1) buf := make([]byte, 65536) for { c1.SetReadDeadline(time.Now().Add(networkTimeout)) n, err := c1.Read(buf) if err != nil { return err } atomic.AddInt64(&bytesProxied, int64(n)) if debug { log.Printf("%d bytes from %s to %s", n, c1.RemoteAddr(), c2.RemoteAddr()) } if s.rateLimit != nil { s.rateLimit(int64(n)) } c2.SetWriteDeadline(time.Now().Add(networkTimeout)) _, err = c2.Write(buf[:n]) if err != nil { return err } } }
// copy Content two-way func pass(from net.Conn, to net.Conn, complete chan bool, one_side chan bool, other_side chan bool) { var err error = nil var bytes []byte = make([]byte, 256) var read int = 0 for { select { case <-other_side: complete <- true return default: from.SetReadDeadline(time.Now().Add(time.Duration(*expire) * time.Second)) read, err = from.Read(bytes) if err != nil { complete <- true one_side <- true return } to.SetWriteDeadline(time.Now().Add(time.Duration(*expire) * time.Second)) _, err = to.Write(bytes[:read]) if err != nil { complete <- true one_side <- true return } } } }
func WriteMessage(conn net.Conn, timeout time.Duration, msg *Message) error { var handle = &codec.MsgpackHandle{} var buf []byte var encoder = codec.NewEncoderBytes(&buf, handle) err := encoder.Encode(msg) if err != nil { return err } length := len(buf) if length > DefaultMessageLengthCap { return errors.New("message is too long") } var lengthBuf [2]byte binary.BigEndian.PutUint16(lengthBuf[:], uint16(length)) conn.SetWriteDeadline(time.Now().Add(timeout)) _, err = conn.Write(lengthBuf[:]) if err != nil { return err } _, err = io.Copy(conn, bytes.NewBuffer(buf)) return err }
func write(conn net.Conn, content []byte, timeout float64) error { if timeout > 0 { conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout) * time.Second)) } _, err := conn.Write(content) return err }
func (c *GsiScanClient) sendRequest( conn net.Conn, pkt *transport.TransportPacket, req interface{}) (err error) { timeoutMs := c.writeDeadline * time.Millisecond conn.SetWriteDeadline(time.Now().Add(timeoutMs)) return pkt.Send(conn, req) }
func NewConn(client *Client, network, addr string, connectTimeout, readTimeout, writeTimeout time.Duration) (*Conn, error) { client.CountNewConn++ var conn net.Conn var err error if connectTimeout > 0 { conn, err = net.DialTimeout(network, addr, connectTimeout) } else { conn, err = net.Dial(network, addr) } if err != nil { return nil, err } if readTimeout > 0 { conn.SetReadDeadline(time.Now().Add(readTimeout)) } if writeTimeout > 0 { conn.SetWriteDeadline(time.Now().Add(writeTimeout)) } this := &Conn{ Conn: conn, Client: client, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, } return this, nil }
func serveSPDYNoNPN(conn net.Conn, srv *http.Server, version, subversion int) { defer common.Recover() tlsConn, ok := conn.(*tls.Conn) if !ok { // Only allow TLS connections. return } if d := srv.ReadTimeout; d != 0 { conn.SetReadDeadline(time.Now().Add(d)) } if d := srv.WriteTimeout; d != 0 { conn.SetWriteDeadline(time.Now().Add(d)) } if err := tlsConn.Handshake(); err != nil { return } serverConn, err := NewServerConn(tlsConn, srv, version, subversion) if err != nil { log.Println(err) return } serverConn.Run() }
// Send all the bytes, but respect the upload limit (force delays) func SockWrite(con net.Conn, buf []byte) (n int, e error) { var tosend int bw_mutex.Lock() TickSent() if UploadLimit == 0 { tosend = len(buf) } else { tosend = int(UploadLimit) - ul_bytes_so_far if tosend > len(buf) { tosend = len(buf) } else if tosend < 0 { tosend = 0 } } ul_bytes_so_far += tosend bw_mutex.Unlock() if tosend > 0 { // Set timeout to prevent thread from getting stuck if the other end does not read con.SetWriteDeadline(time.Now().Add(250 * time.Millisecond)) n, e = con.Write(buf[:tosend]) bw_mutex.Lock() UlBytesTotal += uint64(n) ul_bytes_priod += uint64(n) bw_mutex.Unlock() if e != nil { if nerr, ok := e.(net.Error); ok && nerr.Timeout() { e = nil } } } else { time.Sleep(250 * time.Millisecond) } return }
func tcpSend(conn net.Conn, bytesStream []byte, timeout time.Duration) error { if err := conn.SetWriteDeadline(time.Now().Add(timeout)); err != nil { return err } if _, err := conn.Write(bytesStream); err != nil { return err } return nil }
func writeMessage(conn net.Conn, m *Message) error { conn.SetWriteDeadline(time.Now().Add(idleWriteTimeout)) if err := json.NewEncoder(conn).Encode(m); err != nil { return err } // Jon wants double newline after each message. _, err := conn.Write([]byte("\n\n")) return err }
func Send(addr string, conn net.Conn, params ...string) error { msg := strings.Join(params, " ") + "\n" log.Printf("%s <- %s", addr, msg) if err := conn.SetWriteDeadline(time.Now().Add(5 * time.Second)); err != nil { return err } _, err := io.WriteString(conn, msg) return err }
func (self *Http) initConnection(conn net.Conn) { now := time.Now() readDeadline := now.Add(CONNECTION_READ_TIMEOUT_SECOND * time.Second) conn.SetReadDeadline(readDeadline) writeDeadline := readDeadline.Add(CONNECTION_READ_TIMEOUT_SECOND * time.Second) conn.SetWriteDeadline(writeDeadline) }
// testWriteTimeout tests that Write timeouts do not affect Read. func testWriteTimeout(t *testing.T, c1, c2 net.Conn) { go chunkedCopy(c2, rand.New(rand.NewSource(0))) c1.SetWriteDeadline(aLongTimeAgo) _, err := c1.Write(make([]byte, 1024)) checkForTimeoutError(t, err) if _, err := c1.Read(make([]byte, 1024)); err != nil { t.Errorf("unexpected Read error: %v", err) } }
func (cons *Socket) sendAck(conn net.Conn, success bool) error { if cons.acknowledge != "" { var err error conn.SetWriteDeadline(time.Now().Add(cons.ackTimeout)) if success { _, err = fmt.Fprint(conn, cons.acknowledge) } else { _, err = fmt.Fprint(conn, "NOT "+cons.acknowledge) } return err } return nil }
func (this *Server) send(buf []byte, conn net.Conn) error { conn.SetWriteDeadline(time.Now().Add(this.connTimeout)) num, err := conn.Write(buf) if err != nil { return err } if num <= 0 { return fmt.Errorf("connection write back %d bytes error", num) } return nil }
func setupHeartbeat(c net.Conn) { for { time.Sleep(1 * time.Second) c.SetWriteDeadline(time.Now().Add(3 * time.Second)) _, err := c.Write([]byte("ping")) if err != nil { l.Log("Couldn't connect to server. Check your network connection, and run client again.") os.Exit(1) } } }
//发送数据 3秒超时删除连接 func (this *MsgBox) SendMsg(key string, conn net.Conn, msg *SimpleMsg) { if conn != nil { conn.SetWriteDeadline(time.Now().Add(time.Second * 3)) _, err := conn.Write(msg.ToData()) //包续传先不管 if err != nil { conn.Close() this.Conns.Remove(key) SysLog.PutLineAsLog(fmt.Sprintf("Msgbox%s SendMsg: %s ERROR:%s", this.BoxId, msg.MsgBody, err.Error())) } } else { this.Conns.Remove(key) } }
// Write a packet to the conn. func (w *FixWriter) WritePacket(conn net.Conn, packet []byte) error { if w.timeout > 0 { conn.SetWriteDeadline(time.Now().Add(w.timeout)) } else { conn.SetWriteDeadline(time.Time{}) } if _, err := conn.Write(packet); err != nil { return err } return nil }
// poolWorker sends data to APNS. A different connection receives the APNS responses. func poolWorker(wg *sync.WaitGroup, manager ConnManager, requests <-chan workerRequest, maxWaitTime int) { defer wg.Done() var conn net.Conn = nil var err error var closed <-chan bool lastRequestTime := time.Now() for request := range requests { curTime := time.Now() if conn != nil { // Ensure we'll automatically reconnect on a request if we know the connection was closed. This is non-blocking. select { case <-closed: conn = nil default: } } if conn != nil && curTime.Sub(lastRequestTime) > CLOSE_TIMEOUT { // Close and re-open the connection if the connection has been inactive for over an hour. conn.Close() conn = nil closed = nil } lastRequestTime = curTime if conn == nil { // Lazily attempt to open a connection. If that fails, tell the requester that the connection failed. conn, closed, err = manager.NewConn() if err != nil { request.Response <- &PermanentError{Err: err} conn = nil continue } } deadline := time.Now().Add(time.Duration(maxWaitTime) * time.Second) conn.SetWriteDeadline(deadline) err := writen(conn, request.Payload) if err != nil { request.Response <- &TemporaryError{Err: err, Endpoint: conn.RemoteAddr()} conn.Close() conn = nil closed = nil continue } request.Response <- nil } if conn != nil { conn.Close() conn = nil closed = nil } }