std.socket - problems closing socket

simendsjo simendsjo at gmail.com
Mon Oct 3 11:41:14 PDT 2011


On 03.10.2011 20:02, Regan Heath wrote:
> On Mon, 03 Oct 2011 17:33:57 +0100, simendsjo <simendsjo at gmail.com> wrote:
>> Yes. I've coded the client as follows:
>> 1) start listening socket
>> 2) wait for incoming connections or incoming data
>> 3) receive(). If a socket returns 0 or -1, close it and process next
>> with data
>> 4) read fastcgi request from server
>> 5) write fastcgi response
>> 6) write fastcgi EndRequest (the server should now end the request)
>> 7) if the application should close the request, send shutdown(send)
>> 8) accept incoming connection
>> 9) back to 2)
>>
>> FastCGI connections works in one of two ways: the server is
>> responsible for closing the connections (supports mulitplexing) or the
>> application should close the connection after a request has been sent.
>> For the latter I send SocketShutdown.SEND after writing EndRequest in
>> step 6), but it doesn't really matter as nginx doesn't support
>> multiplexing. It closes the connection after each request anyway. I
>> see the same result no matter what option I use.
>
> Ok, so your "client" (that you have coded) is also the "application" you
> refer to in the bit about FastCGI above? Or are there 2 components here,
> and are both written in D?


It's just one component to handle FastCGI requests. I didn't want to 
rely on the external libfcgi.


> Does the fastcgi "EndRequest" close the socket/connection? If so, doing
> a socket.Shutdown /after/ this is not going to work as the socket has
> already been closed (which implicitly does a shutdown(BOTH)). In that
> case, try doing the shutdown /before/ the EndRequest, and make sure you
> also read any/all data remaining on the socket before doing the
> EndRequest/close.


EndRequest doesn't really close the socket, it's just a message to the 
server telling that the full response is written (request handled). If 
the server (nginx) is responsible, it can reuse the connection to give 
other requests. If the server says that the application is responsible, 
shutdown(send) is called. This is part of the specification.


> The key question seems to be, at which point does nginx close the
> connection? and therefore, is there any unread data on the socket (at
> either end) when it does. If, for example, it flushes the response to
> the other end, but does not wait for it to be read, and closes the
> socket, you will get CONNRESET/ABORTED errors on the other end.
 >
>> I'm running the exact same request and writing the exact same response
>> for all queries, so there shouldn't be any unknown fields.
>
> I didn't mean unknown "field" I mean extra data of any kind, but I
> suspect you're using an API to form the requests etc so this is probably
> not the case.
>
>> I also only get an error on <1/5 of the requests, and even when the
>> error occurs, the response has been written completely to the browser.
>
> Ahh, ok, I believe the problem is simply the timing of the
> 'close/EndRequest'. Sometimes it happens /before/ the data has been
> completely read (1/5), other times after (4/5).
>
> R


It seems nginx is to blame here, and not me. I tried Lighttp and it 
works. It gives several EWOULDBLOCK, but I can just handle these again 
with no problem. I should have tried this sooner... I've used a lot of 
time trying to track down these problems :|

Thanks for all your help - I'll update this thread if I find a solution 
to the nginx issue.


More information about the Digitalmars-d-learn mailing list