Strange socket error

Bob Cowdery bob at bobcowdery.plus.com
Thu Dec 23 01:25:17 PST 2010


Hi Heywood

Thankyou for your time. Yes I agree making the call blocking does stop
the exceptions churning. Unfortunately the application stops accepting
data now because after the first incoming transfer from the web socket
client it sees data on the listening socket and promptly blocks on it
and never comes off until I make another connection. I think this is
expected behaviour. I could spawn a thread for each connection which I
would normally do but shouldn't need to as it's really only a few users
and I believe that would only sidestep the real problem.

There are lots of things here that don't make sense.

1. It works for Windows and it should work for Linux (and Mac) unless
Windows is broken and Linux is behaving as it should.
2. I should only see data on the listen socket when I make a new
connection. What I see is data on the listen socket when I send data on
the connected socket and with non-blocking even when I don't make a
connection or send any data at all.
2. The really confusing thing is if I stop my USB and DSP threads it
stops behaving like this and sees data on the correct sockets. In other
words it works as it does on Windows so I have to assume this is the
correct behaviour.
3. I've played around with trying to figure out exactly what it is in
the other threads that causes the behaviour. I got as far as finding
that only the DSP thead is required so that rules out misbehaving USB.
Very oddly there is a loop that is creating some Json data (not very
efficiently) as it's doing a lot of string concatenation. If I comment
out this loop or reduce its iterations the exception slow down to the
point where I just get 2 and then they stop. This points to something
horrible going on.

I can only hope I've done something stupid that I just happen to be
getting away with on Windows. If it's a bug in the compiler or libraries
I think I'm stuffed as I wouldn't know where to start.

Regards
bob

On 23/12/2010 00:20, Heywood Floyd wrote:
> Hi Bob!
>
>
> My guess: You're listener is set to be non-blocking. That means that when you call listener.accept() it will return immediately with an SocketAcceptException, if there's no connection. And you're basically calling listener.accept() over and over again in an infinite loop.
>
> The following example shows it:
>
> import std.concurrency, std.stdio, std.conv, std.socket;
> void main()
> {
> 	ushort port = 9999;
> 	Socket listener = new TcpSocket;
> 	assert(listener.isAlive);
> 	listener.blocking = false;
> 	listener.bind(new InternetAddress(port));
> 	listener.listen(10);
> 	writeln("Listening on port: ", port);
> 	Socket sn;
> 	while(true){
> 		try
> 		{
> 			writeln ("Accepting");
> 			sn = listener.accept();
> 			writeln("Connection from ", sn.remoteAddress().toString(), " established" );
> 			assert(sn.isAlive);
> 			assert(listener.isAlive);
> 			break;
> 		}
> 		catch(Exception e)
> 		{
> 			writeln("Error accepting: ", e.toString() );
> 			if(sn)
> 			sn.close();
> 		}
> 	}
> 	writeln("end");
> }
>
> Running the example will print
>     Error accepting: std.socket.SocketAcceptException: Unable to accept socket connection: Resource temporarily unavailable
> for ever. (Tested on Mac.) When a user connects to 127.0.0.1:9999 (by for instance opening the URL in a browser) socket.accept _does_ return a connection and the program prints "end".
>
> I don't know why the program doesn't do this on Windows. As far as I can tell the endless exceptions _is_ the correct behaviour, right?
>
> Anyway, if you comment out the the line
>     listener.blocking = false;
> in 'listener.d', does it work as intended then? In the example above this will cause the listener.accept()-call to actually wait until it gets a connection, and thus not spew out all the exceptions.
>
> BR
> /heywood
>
>
>
>
> Bob Cowdery Wrote:
>
>> Hi all,
>>
>> This is a long shot but I'm out of ideas. I ported an app from Windows
>> to Linux and after many issues it is working but I'm left with a strange
>> problem. The app basically reads data streams from a USB device,
>> processes them and outputs real-time graphical data to a browser. There
>> is also some control input from the browser. The interface to the
>> browser is web sockets for which I have written a D web-socket server.
>> Depending on how much of my application I allow to run I get a stream of
>> these errors.
>>
>> Error accepting: std.socket.SocketAcceptException: Unable to accept
>> socket connection: Resource temporarily unavailable
>> ----------------
>> ./DcSdr() [0x80aa2ed]
>> ./DcSdr() [0x806f52b]
>> ./DcSdr() [0x804f752]
>> ./DcSdr() [0x809b422]
>> ./DcSdr() [0x80ae77e]
>> /lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0x48496e]
>> /lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xc5fa4e]
>>
>> This is the web-socket accept. I seem to fall straight through the
>> accept call even when I am not making any connection attempt. When I do
>> connect the stream stops and I get one of these outputs each time I send
>> data from the browser. I should not even be near the accept at that
>> point as the connection is made.
>>
>> The app appears to be unaffected and works as expected. The odd think is
>> if I shut down part of the app these errors stop. I can't tie it down to
>> any specific thing but I suspect threading as the number of threads is
>> reduced by stopping parts of the app. The error also seems to indicate
>> threads are involved. I did not get this problem on Windows.
>>
>> Any ideas would be much appreciated.
>>
>> Thanks
>> bob



More information about the Digitalmars-d-learn mailing list