KeepAlive with net.Listen

143 views
Skip to first unread message

Rohit Roy Chowdhury

unread,
Feb 10, 2024, 1:08:10 AMFeb 10
to golang-nuts
Hello fellow gophers, I am currently building an experimental HTTP/1.1 framework based on TCP sockets as part of my course project. In project requirements, I have been asked to make a web server which can handle keep-alive properly without using the net/http library. The project link can be found below:
I have recently found out that if I SetKeepAlive(true) and SetKeepAlivePeriod(time.Second * time.Duration(timeout)), it is not enough to hold the connection. Additionally, any subsequent requests are freezing.
Screenshot 2024-02-09 at 9.39.08 PM.png

Then I found out that net/http's Transport manages a pool for idle connections. I want to go for a similar approach for my project. But I am not able to figure out how to detect income requests for my idle connections that I will be storing in the pool. Specifically, I want to know how listener.Accept() can give me an idle connection if it exists in the pool.

Brian Candler

unread,
Feb 10, 2024, 4:52:23 AMFeb 10
to golang-nuts
Handling keep-alives on the *server* side doesn't require any sort of connection pool. Just create one goroutine for each incoming TCP connection, and once you've handled one request, loop around, waiting for another request on the same connection.

(That's assuming the client does request use of keep-alives of course; if they don't, you should close the connection. This depends on which HTTP version they requested and the Connection: header if present. Full details in RFC 2616)

Rohit Roy Chowdhury

unread,
Feb 10, 2024, 2:12:42 PMFeb 10
to golang-nuts
Thanks, that makes so much sense. So should I long-poll until next request line comes or keep-alive times out? Is there a better way to detect incoming requests and then maybe awake the goroutine using channels?

Brian Candler

unread,
Feb 11, 2024, 12:37:43 PMFeb 11
to golang-nuts
You're thinking backwards. "Long polling" is something done at the *client* side: this is where you send a HTTP request, but the reply intentionally doesn't come back for a long time - generally until the server detects some event that needs reporting.

At a web *server*, you simply read the request from the socket(*), process it, reply, and go straight back to reading the next request. Read will block until the next request comes in (or the connection is closed).  In other words, the goroutine handling that TCP connection just has a loop. There's no need to "wake" this goroutine from anywhere.

(*) You need to read until the end of the request (request headers + body, if any). Again, RFC2616 tells you how the request is delimited - see section 5.

Rohit Roy Chowdhury

unread,
Feb 11, 2024, 4:21:48 PMFeb 11
to golang-nuts
I got your point. But reader.ReadString('\n') does not block like you said. After a request gets parsed, from the next iteration it keeps on emitting io.EOF until next request arrives.

Robert Engels

unread,
Feb 11, 2024, 5:30:44 PMFeb 11
to Rohit Roy Chowdhury, golang-nuts
There is no such thing as a pool of idle connections at the tcp level. As each side of the connection is bound to a specific port on both ends and can’t be unbound. 

You may be referring to http over tcp where the client and server do not close the connection after each request - they keep it open for the next request from that client. Http2 complicates this a bit as it has multiple connections over a single tcp connection. 

On Feb 11, 2024, at 4:22 PM, 'Rohit Roy Chowdhury' via golang-nuts <golan...@googlegroups.com> wrote:

I got your point. But reader.ReadString('\n') does not block like you said. After a request gets parsed, from the next iteration it keeps on emitting io.EOF until next request arrives.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/919a5a2d-bd99-4f9c-b9fd-cfa2bd0a3862n%40googlegroups.com.

Rohit Roy Chowdhury

unread,
Feb 11, 2024, 5:36:19 PMFeb 11
to golang-nuts
Yes I got it but I want to know if reader.ReadString("\n") is supposed to throw io.EOF rather than blocking for next request in the connection.

Robert Engels

unread,
Feb 11, 2024, 7:49:09 PMFeb 11
to Rohit Roy Chowdhury, golang-nuts

If you have http keep alive on - either side should block when reading - it is a full duplex connection. You will only get eof if the tcp connection is closed. 

If http keep alive is off, then the connection is closed after the server sends the response - the tcp protocol allows the client to read this data even though the connection is shut down. 

On Feb 11, 2024, at 5:36 PM, 'Rohit Roy Chowdhury' via golang-nuts <golan...@googlegroups.com> wrote:

Yes I got it but I want to know if reader.ReadString("\n") is supposed to throw io.EOF rather than blocking for next request in the connection.

Rohit Roy Chowdhury

unread,
Feb 11, 2024, 7:54:25 PMFeb 11
to golang-nuts
As stated earlier, objective is to create a web server without using net/http, instead directly reading from the socket connection.

Robert Engels

unread,
Feb 11, 2024, 8:00:02 PMFeb 11
to Rohit Roy Chowdhury, golang-nuts
If it is a web server that supports http clients you still have to implement the protocol correctly. At the lowest level that is what all web server implementations do - they read from the socket directly. 

On Feb 11, 2024, at 7:54 PM, 'Rohit Roy Chowdhury' via golang-nuts <golan...@googlegroups.com> wrote:

As stated earlier, objective is to create a web server without using net/http, instead directly reading from the socket connection.

Rohit Roy Chowdhury

unread,
Feb 11, 2024, 8:25:16 PMFeb 11
to golang-nuts
Yes I did implement. You can check it here.

Robert Engels

unread,
Feb 11, 2024, 8:56:41 PMFeb 11
to Rohit Roy Chowdhury, golang-nuts
If you implemented it and it works - I guess I don’t understand your question. You must know how tcp/http works. 

On Feb 11, 2024, at 8:25 PM, 'Rohit Roy Chowdhury' via golang-nuts <golan...@googlegroups.com> wrote:

Yes I did implement. You can check it here.
Reply all
Reply to author
Forward
0 new messages