In article <[EMAIL PROTECTED]>, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> writes:
I have had some difficulty following the assertions, corrections, and misquoting in this article thread, so apologies in advance if I have missed a correction or misunderstood an assertion. [ quoting partially corrected: ] >> ---------------------------------------------------------------- >> Here is the example above converted to a more straightforward udp >> client that isolates the part I am asking about: >> >> import socket, sys >> >> host = 'localhost' #sys.argv[1] >> port = 3300 >> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) >> >> data = 'hello world' >> num_sent = 0 >> while num_sent < len(data): >> num_sent += s.sendto(data, (host, port)) >> >> print "Looking for replies; press Ctrl-C or Ctrl-Break to stop." >> while 1: >> buf = s.recv(2048) >> >> #Will the following if statement do anything? >> if not len(buf): >> break >> >> print "Received from server: %s" % buf >> -------------------------------------------------------------- > But, for the specific case that you have asked about, since the > default for timeout is no timeout, or block forever, your question: > > #Will the following if statement do anything? > if not len(buf): > break > > The answer is that you are right, it will do nothing. But, if you set > a time out on the socket, and you receive no data and the timeout > expires, checking for the length of zero and a break is one way to > jump out of the loop if you need to. That is not correct in my experience. The test "not len(buf)" -- or perhaps more clearly "len(buf) == 0" is a valid way, perhaps the preferred way, of detecting a zero length datagram as transmitted via UDP (socket.SOCK_DGRAM). Zero length datagrams are perfectly valid in UDP and in fact are the recommended way of initiating certain protocol actions. See, for example, the Time Protocol (RFC 868, top of page 2). While POSIX regular files and TCP streams use a zero read result to indicate end-of-file, the action is different for "message-based sockets" (and STREAMS). In the case of UDP, there is no concept of end-of-file, and thus no API mechanism for indicating such. Instead, the zero return is used to indicate a zero-length message. Timeouts are indicated by raising an exception: - In the case of the settimeout method of socket, a socket.timeout exception is raised. - In the case of use of socket option socket.SO_SNDTIMEO, a socket.error exception is raised w/ errno = EAGAIN. > For example: > > import socket, sys > > host = 'localhost' #sys.argv[1] > port = 3300 > s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) > > s.settimeout(1.0) > buf = '' > > data = 'hello world' > num_sent = 0 > > while num_sent < len(data): > num_sent += s.sendto(data, (host, port)) > > print "Looking for replies; press Ctrl-C or Ctrl-Break to stop." > while True: > > try: > buf, addr = s.recvfrom(2048) > except: > pass > > #Will the following if statement do anything? > # In this case it will cause the script to jump out of the loop > # if it receives no data for a second. > if not len(buf): > break > > print "Received from server: %s" % buf The reason that this example *seems* to work is that you mask the exception. What is actually happening is that the timeout of the recvfrom call raises socket.timeout, which is ignored. Then because buf has been explicitly set to zero length (near the beginning of the program), and because it is *not* modified as a result of the recvfrom call, the length is still zero, and the break is executed. Try commenting out the try/except construct, or try actually providing at least one non-zero length response (such that buf is modified) and seeing if it ever terminates. I would also like to point out that the original example (quoted from the book) used "connect' and "recv" w/ UDP). One of the purposes of using this construct (rather than using "recvfrom") is to simplify identification of the remote system: When you "connect" to a UDP socket, the OS will only send messages to that system and will ignore messages that do not originate from that IP address (ignoring the issue IP address spoofing). - dmw -- . Douglas Wells . Connection Technologies . . Internet: -sp9804- -at - contek.com- . -- http://mail.python.org/mailman/listinfo/python-list