problem with sockets under win32; premature connection termination

Chris Miller chris at dprogramming.com
Thu May 10 16:20:26 PDT 2007


On Thu, 10 May 2007 18:55:05 -0400, Downs <default_357-line at yahoo.de>  
wrote:

> The following code should theoretically wait for a single TCP  
> connection, and transfer a file over it.
>
> import std.stdio, std.socket, std.string, std.file;
>
> void main(char[][] args) {
>   auto l=new Socket(AddressFamily.INET, SocketType.STREAM,  
> ProtocolType.TCP);
>   l.blocking=true;
>   with (l) {
>    bind(new InternetAddress("0.0.0.0", atoi(args[1])));
>    listen(16);
>   }
>   auto request=l.accept;
>   request.send("HTTP/1.0 200 OK\r\n\r\n");
>   request.send(read(args[2]));
>   request.shutdown(SocketShutdown.BOTH);
>   request.close;
> }
>
> Trying to use this program to host a file (images work best), I ran into  
> the following problem:
> the image would transmit, partially, then the request.send call would  
> return - prematurely -
> and the rest of the unsent data would be silently discarded.
> Experimenting with linger and SetOption produced no discernible effect.
> I've tried to find a solution to this problem for weeks now, but I don't  
> seem to be making headway.
>
> Halp? ;_;
>
>   -- downs
>
> PS: If you try to replicate it, it is recommended to use a mid-latency  
> connection so that the transfer doesn't complete immediately.
> PPS: Interestingly, it works with netcat. Firefox, IE and Opera break  
> though.

Socket.send doesn't guarantee the whole thing will send; it returns how  
many bytes are buffered to be sent. You should loop until it reports all  
the bytes are buffered to be sent, or use SocketStream, which does this  
for you. Also, using Socket.shutdown to shutdown sends/writes (included by  
BOTH) might be aborting the unsent buffer. Finally, after these  
appropriate changes, I believe there's still a chance that the whole  
buffer won't be sent if the linger time expires before the whole buffer  
was able to send.



More information about the Digitalmars-d mailing list