[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

sockets -- basic udp client

7stud --

2/15/2008 10:24:00 PM

My question pertains to this example:

#!/usr/bin/env python

import socket, sys, time

host = sys.argv[1]
textport = sys.argv[2]

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
port = int(textport)
except ValueError:
# That didn't work. Look it up instread.
port = socket.getservbyname(textport, 'udp')

s.connect((host, port))
print "Enter data to transmit: "
data = sys.stdin.readline().strip()
s.sendall(data)
s.shutdown(1)
print "Looking for replies; press Ctrl-C or Ctrl-Break to stop."
while 1:
buf = s.recv(2048)
if not len(buf):
break
print "Received: %s" % buf


As far as I can tell, the if statement:

if not len(buf):
break

does nothing. Either recv() is going to read some data or it's going
to block. My understanding is that udp sockets do not have a
connection, so the server can't close the connection--hich would cause
a blank string to be sent to the client.

So, as far as I can tell, the only way that code would make sense is
if the server were programmed to send a blank string to the client
after it sent data to the client. Is that correct?
12 Answers

Gabriel Genellina

2/16/2008 1:49:00 AM

0

En Fri, 15 Feb 2008 20:24:19 -0200, 7stud <bbxx789_05ss@yahoo.com>
escribió:

> My question pertains to this example:
>
> #!/usr/bin/env python
>
> import socket, sys, time
>
> host = sys.argv[1]
> textport = sys.argv[2]
>
> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> try:
> port = int(textport)
> except ValueError:
> # That didn't work. Look it up instread.
> port = socket.getservbyname(textport, 'udp')
>
> s.connect((host, port))
> print "Enter data to transmit: "
> data = sys.stdin.readline().strip()
> s.sendall(data)
> s.shutdown(1)
> print "Looking for replies; press Ctrl-C or Ctrl-Break to stop."
> while 1:
> buf = s.recv(2048)
> if not len(buf):
> break
> print "Received: %s" % buf
>
>
> As far as I can tell, the if statement:
>
> if not len(buf):
> break
>
> does nothing. Either recv() is going to read some data or it's going
> to block. My understanding is that udp sockets do not have a
> connection, so the server can't close the connection--hich would cause
> a blank string to be sent to the client.
>
> So, as far as I can tell, the only way that code would make sense is
> if the server were programmed to send a blank string to the client
> after it sent data to the client. Is that correct?

That example is plain wrong; looks like some TCP code but with SOCK_STREAM
blindy replaced with SOCK_DGRAM. connect, sendall and recv are not used
for UDP; sendto and recvfrom are used instead. There are some examples in
the Demo python directory.

--
Gabriel Genellina

7stud --

2/16/2008 7:57:00 AM

0

On Feb 15, 6:48 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
> En Fri, 15 Feb 2008 20:24:19 -0200, 7stud <bbxx789_0...@yahoo.com>  
> escribió:
>
>
>
> > My question pertains to this example:
>
> > #!/usr/bin/env python
>
> > import socket, sys, time
>
> > host = sys.argv[1]
> > textport = sys.argv[2]
>
> > s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> > try:
> >     port = int(textport)
> > except ValueError:
> >     # That didn't work.  Look it up instread.
> >     port = socket.getservbyname(textport, 'udp')
>
> > s.connect((host, port))
> > print "Enter data to transmit: "
> > data = sys.stdin.readline().strip()
> > s.sendall(data)
> > s.shutdown(1)
> > print "Looking for replies; press Ctrl-C or Ctrl-Break to stop."
> > while 1:
> >     buf = s.recv(2048)
> >     if not len(buf):
> >         break
> >     print "Received: %s" % buf
>
> > As far as I can tell, the if statement:
>
> > if not len(buf):
> >    break
>
> > does nothing.  Either recv() is going to read some data or it's going
> > to block.   My understanding is that udp sockets do not have a
> > connection, so the server can't close the connection--hich would cause
> > a blank string to be sent to the client.
>
> > So, as far as I can tell, the only way that code would make sense is
> > if the server were programmed to send a blank string to the client
> > after it sent data to the client.  Is that correct?
>
> That example is plain wrong; looks like some TCP code but with SOCK_STREAM  
> blindy replaced with SOCK_DGRAM. connect, sendall and recv are not used  
> for UDP; sendto and recvfrom are used instead. There are some examples in  
> the Demo python directory.
>
> --
> Gabriel Genellina

On Feb 15, 6:48 pm, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
> En Fri, 15 Feb 2008 20:24:19 -0200, 7stud <bbxx789_0...@yahoo.com>  
> escribió:
>
>
>
> > My question pertains to this example:
>
> > #!/usr/bin/env python
>
> > import socket, sys, time
>
> > host = sys.argv[1]
> > textport = sys.argv[2]
>
> > s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> > try:
> >     port = int(textport)
> > except ValueError:
> >     # That didn't work.  Look it up instread.
> >     port = socket.getservbyname(textport, 'udp')
>
> > s.connect((host, port))
> > print "Enter data to transmit: "
> > data = sys.stdin.readline().strip()
> > s.sendall(data)
> > s.shutdown(1)
> > print "Looking for replies; press Ctrl-C or Ctrl-Break to stop."
> > while 1:
> >     buf = s.recv(2048)
> >     if not len(buf):
> >         break
> >     print "Received: %s" % buf
>
> > As far as I can tell, the if statement:
>
> > if not len(buf):
> >    break
>
> > does nothing.  Either recv() is going to read some data or it's going
> > to block.   My understanding is that udp sockets do not have a
> > connection, so the server can't close the connection--which would cause
> > a blank string to be sent to the client.
>
> > So, as far as I can tell, the only way that code would make sense is
> > if the server were programmed to send a blank string to the client
> > after it sent data to the client.  Is that correct?
>
> That example is plain wrong; looks like some TCP code but with SOCK_STREAM  
> blindy replaced with SOCK_DGRAM. connect, sendall and recv are not used  
> for UDP; sendto and recvfrom are used instead. There are some examples in  
> the Demo python directory.
>


Yes, I agree it's a poor example--it's from 'Foundations of Python
Network Programming'--but it does 'work'. It also doesn't appear to
be a tcp client that was converted too directly into a udp client
because the previously presented tcp examples are different.

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



Another question I have pertains to the docs here:

getservbyname(servicename[, protocolname])
Translate an Internet service name and protocol name to a port number
for that service. The optional protocol name, if given, should be
'tcp' or 'udp', otherwise any protocol will match.


What does a 'servicename' look like?

rluse1@gmail.com

2/16/2008 1:18:00 PM

0


----------------------------------------------------------------
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
--------------------------------------------------------------

There is still a problem with your script.

buf = s.recv(2048) should be changed to

buf, addr = s.recvfrom(2048) or
buf = s.recvfrom(2048)[0]

or something like that since recvfrom returns a pair.

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.

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


For getservbyname and its complement, getservbyport, they are talking
about well known protocols like http, ftp, chargen, etc. The
following script is a very simple example:

import socket

print socket.getservbyname('http')

print socket.getservbyname('ftp')
print socket.getservbyname('time')


print socket.getservbyport(80)


- Bob

Gabriel Genellina

2/16/2008 1:33:00 PM

0

En Sat, 16 Feb 2008 05:56:39 -0200, 7stud <bbxx789_05ss@yahoo.com>
escribi�:

>> > while 1:
>> >     buf = s.recv(2048)
>> >     if not len(buf):
>> >         break
>> >     print "Received: %s" % buf
>>
>> > As far as I can tell, the if statement:
>>
>> > if not len(buf):
>> >    break
>>
>> > does nothing.  Either recv() is going to read some data or it's going
>> > to block.   My understanding is that udp sockets do not have a
>> > connection, so the server can't close the connection--which would
>> cause
>> > a blank string to be sent to the client.
>>
>> > So, as far as I can tell, the only way that code would make sense is
>> > if the server were programmed to send a blank string to the client
>> > after it sent data to the client.  Is that correct?

Your analysis looks correct to me. If it were using TCP, an empty string
signals that the other side has closed the connection, but being UDP it
cannot happen (unless the server explicitely sends an empty string, as you
said).

>> That example is plain wrong; looks like some TCP code but with
>> SOCK_STREAM  
>> blindy replaced with SOCK_DGRAM. connect, sendall and recv are not used
>> for UDP; sendto and recvfrom are used instead. There are some examples
>> in  
>> the Demo python directory.
>
> Yes, I agree it's a poor example--it's from 'Foundations of Python
> Network Programming'--but it does 'work'. It also doesn't appear to
> be a tcp client that was converted too directly into a udp client
> because the previously presented tcp examples are different.

Ok, you *can* use those functions with datagrams too, but it's confusing
(at least for the very first UDP example!)

> Another question I have pertains to the docs here:
>
> getservbyname(servicename[, protocolname])
> Translate an Internet service name and protocol name to a port number
> for that service. The optional protocol name, if given, should be
> 'tcp' or 'udp', otherwise any protocol will match.
>
> What does a 'servicename' look like?

py> import socket
py> socket.getservbyname("http")
80
py> socket.getservbyname("smtp")
25

On Linux the mapping ports<->services is in /etc/services; on Windows see
%windir%\system32\drivers\etc\services

--
Gabriel Genellina

7stud --

2/16/2008 9:26:00 PM

0

On Feb 16, 6:18 am, "rlu...@gmail.com" <rlu...@gmail.com> wrote:
> ----------------------------------------------------------------
> 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
> --------------------------------------------------------------
>
> There is still a problem with your script.
>
> buf = s.recv(2048)  should be changed to
>
> buf, addr = s.recvfrom(2048)  or
> buf = s.recvfrom(2048)[0]
>
> or something like that since recvfrom returns a pair.
>

If you don't care about the address of the sender, e.g. you are not
going to send anything back, is there an advantage to using recv()?
Or, as a matter of course should you always use recvfrom() with udp
sockets?


> 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.
>
> 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
>
> For getservbyname and its complement, getservbyport, they are talking
> about well known protocols like http, ftp, chargen, etc.  The
> following script is a very simple example:
>
> import socket
>
> print socket.getservbyname('http')
>
> print socket.getservbyname('ftp')
> print socket.getservbyname('time')
>
> print socket.getservbyport(80)
>
>  - Bob

Thanks

7stud --

2/16/2008 9:30:00 PM

0

On Feb 16, 6:32 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
> >> That example is plain wrong; looks like some TCP code but with  
> >> SOCK_STREAM  
> >> blindy replaced with SOCK_DGRAM. connect, sendall and recv are not used  
> >> for UDP; sendto and recvfrom are used instead. There are some examples  
> >> in  
> >> the Demo python directory.
>
> > Yes, I agree it's a poor example--it's from 'Foundations of Python
> > Network Programming'--but it does 'work'.  It also doesn't appear to
> > be a tcp client that was converted too directly into a udp client
> > because the previously presented tcp examples are different.
>
> Ok, you *can* use those functions with datagrams too, but it's confusing  
> (at least for the very first UDP example!)
>

Yes, I agree. The book is well written, but the introductory examples
and a lack of explanation of the finer details is a disaster.


> > Another question I have pertains to the docs here:
>
> > getservbyname(servicename[, protocolname])
> > Translate an Internet service name and protocol name to a port number
> > for that service. The optional protocol name, if given, should be
> > 'tcp' or 'udp', otherwise any protocol will match.
>
> > What does a 'servicename' look like?
>
> py> import socket
> py> socket.getservbyname("http")
> 80
> py> socket.getservbyname("smtp")
> 25
>
> On Linux the mapping ports<->services is in /etc/services; on Windows see  
> %windir%\system32\drivers\etc\services
>
> --
> Gabriel Genellina

Thanks.

rluse1@gmail.com

2/17/2008 7:23:00 AM

0

If you don't care about the address of the sender, e.g. you are not
going to send anything back, is there an advantage to using recv()?
Or, as a matter of course should you always use recvfrom() with udp
sockets?


I don't know of a reason why you couldn't use recvfrom() all the time,
and that is what I do. However, I also don't see a reason why you
should
not use recv() if you don't care who the message comes from.
Historically,
though, the ultimate authority on this kind of stuff is

Richard Stevens and his Unix and TCP/IP books

I recommend these books if you want to get into network programming.

Cheers,
Bob

Paul Rubin

2/17/2008 7:28:00 AM

0

"rluse1@gmail.com" <rluse1@gmail.com> writes:
> Historically, though, the ultimate authority on this kind of stuff is
> Richard Stevens and his Unix and TCP/IP books
>
> I recommend these books if you want to get into network programming.

I keep wanting to get that book, but it gets older and older. Have
things really not changed since it was written?

Steve Holden

2/17/2008 9:03:00 AM

0

Paul Rubin wrote:
> "rluse1@gmail.com" <rluse1@gmail.com> writes:
>> Historically, though, the ultimate authority on this kind of stuff is
>> Richard Stevens and his Unix and TCP/IP books
>>
>> I recommend these books if you want to get into network programming.
>
> I keep wanting to get that book, but it gets older and older. Have
> things really not changed since it was written?

TCP is much like a funicular railway: it's been around long enough that
the basic engineering principles are known and the basic bugs have been
ironed out. Stevens is still an excellent reference.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.hold...

Roy Smith

2/17/2008 2:44:00 PM

0

In article "rluse1@gmail.com" <rluse1@gmail.com> wrote:
> If you don't care about the address of the sender, e.g. you are not
> going to send anything back, is there an advantage to using recv()?

At the system call level, recv() is marginally faster since there's less
data to pass back and forth between the kernel and user space. Not that
this is likely to be significant in any real-world application.

The bigger advantage to recv() is that the interface is simpler, so there's
less code to write. For the C interface, using recv() instead of
recvfrom() frees you from having to pass in two arguments that you're not
going to use. From the Python interface, it frees you from having to
unpack the tuple that recvfrom() returns. Instead of:

data, address = recvfrom(bufsize)

you write

data = recv(bufsize)

It's not just a bunch less typing, it's also easier to understand. You
don't leave some future maintainer of your code scratching their head
trying to figure out where 'address' is used, when in fact, it's not.