I am working on a project in the Go language which includes TCP server. I am trying to implement an idle timeout on server sockets, but couldn't do it. The Go code I am using goes like this:
package main
import (
"bufio"
"fmt"
"net"
"os"
"strconv"
"time"
)
func main() {
startServer(6666, time.Duration(2)*time.Second)
}
func startServer(port int, deadline time.Duration) {
// Listen for incoming connections.
strPort := strconv.Itoa(port)
l, err := net.Listen("tcp", ":"+strPort)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
fmt.Println("Listening on port:" + strPort)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
fmt.Println("Got new connection")
// Set read timeout
conn.SetReadDeadline(time.Now().Add(deadline))
// Handle connections in a new goroutine.
go handleRequest(conn)
}
}
func handleRequest(conn net.Conn) {
reader := bufio.NewReader(conn)
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Println(scanner.Bytes())
}
}
I want it to timeout and close the connection after 2 seconds. Could anybody please tell me what I might be doing wrong. In order to test it, I am using a TCP client I wrote as Python scipt. The client code goes like this:
λ python
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from socket import *
>>> c = socket(family=AF_INET, type=SOCK_STREAM)
>>> c.connect(('localhost', 6666))
I can always keep track of all the open connections, along with their last active time in some sort of data structure and launch a goroutine which periodically checks for time elapsed for every connection, closing the ones I haven't heard from in a while. But I wanted to utilize the built-in method SetReadDeadline()
for the job.