Alan,

Yup, you got my point.  That is completely correct that the Java code I attached will always only wait and then timeout.  As you said, the question is should it be a timeout exception or an exception that it is an error to do a recv on an unbound socket.

What you are proposing is a more meaningful message, but it does change from the existing "norm" in Python and in Java and I think in the underlying BSD sockets which the Python Library Reference lists in the first line of the Socket section.  The question to me is would it make things better or worse to change?  I would also like to hear what other people have to say.

Well, I think I'll stop by Borders's on the way home from work.  Its time that I bought Stevens. 

 - Bob



-----Original Message-----
From: Alan Kennedy <jython-dev@xhaus.com>
To: boblusebob@aim.com
Cc: jython-dev@lists.sourceforge.net
Sent: Wed, 5 Mar 2008 12:31 pm
Subject: Re: [Jython-dev] UDP Timeout

[Bob]
>  I'm sorry, I'm not being very clear.
>
>  I do not want the sendto command to timeout.  I want the recvfrom command
> to timeout.
>
>  The system that I am using during the day today is a Windows 2003 Server.
> Using either the bind or the sendto, the script and Jython are performing
> properly.  With Jython 2.2.1, my original script (unbound socket) causes me
> to have to kill the JVM, and using trunk, it does indeed get the error that
> you demonstrated to me.

OK, to be explicitly clear, you are simply using the sendto() method
to cause creation of the underlying socket, so that by the time your
code has entered the recvfrom() method, there will actually be an
underlying socket which can timeout.

So, using your original code snippet, and adding a sendto() (instead
of a bind()) to cause creation of a socket, we get this code

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import socket, sys

import time



host =  'localhost'

port = 10000

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.sendto("testdata", ("www.jython.org", 10000) )

#s.bind( (host, port) )
# The actual UDP socket now exists
s.settimeout(5.0)



while True:



    print '\nThe socket timeout is set to:', s.gettimeout()

    print sys.version



    try:

        start = time.time()

        buf, addr = s.recvfrom(2048)

    except socket.timeout, to:

        print '\nsocket timeout exception', to

        print '\nTimer expired in:', time.time() - start, ' seconds'

        break

    except socket.error, se:

        print '\nsocket.error', se

    except:

        print 'Other error'
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Which gives the following, i.e. the expected behaviour, when I run it
(on Ubuntu)

"""
The socket timeout is set to: 5.0
2.2.1

socket timeout exception timed out

Timer expired in: 5.009999990463257  seconds
"""

Have I misunderstood your intention?

[Bob]
>  Regardless the unbound UDP socket in Jython needs to be handled.

It is already handled, as we have already uncovered in this thread:
unfortunately, the exception currently raised is an AssertionError. I
believe that attempting to recv/recvfrom on an unbound UDP socket
should raise a different exception, perhaps

socket.error(ENOTCONN, "Cannot recv/recvfrom on unbound socket")

[Bob]
>  As far as Python doing a timeout on a nonbound port, I don't think it is
> actually a "problem".  I coded the same type of script in a Java program and
> it timed out.  I have attached it.
>
>  I also think it will work this way, recv timing out on an unbound UDP port
> in c and unix.  I will test tonight on my Linux system.
>
>  It looks to me to be something that will have to be a minor difference
> between Python and Jython.

I see your java code, and it looks fine and reasonable. But it will
always throw a timeout exception.

It is a peculiarity of the jython socket implementation that this
situation has come to light. We can easily emulate the cpython
behaviour (which I consider to be a trap for the unwary at best, or
defective at worst), by recoding the recvfrom method like so

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    def recvfrom(self, num_bytes, flags=None):
        try:
            # assert self.sock_impl
            if not self.sock_impl:
                self.sock_impl = _datagram_socket_impl()
            return self.sock_impl.recvfrom(num_bytes, flags)
        except java.lang.Exception, jlx:
            raise _map_exception(jlx)
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

But IMHO this is deluding the user; we can and should inform the user
that the operation they have requested is meaningless, by raising an
exception.

Anybody else got some thoughts on this? Is it worth deviating from
cpython behaviour in this case? Or should we simply follow cpython's
lead?

Alan.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Jython-dev mailing list
Jython-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jython-dev