socket send help

Discussion in 'Python' started by greywine@gmail.com, Dec 24, 2008.

  1. Guest

    Hi everyone,

    New guy here. I'm trying to figure out sockets in order to one day do
    a multiplayer game. Here's my problem: even the simplest examples
    don't work on my computer:

    A simple server:

    from socket import *
    myHost = ''
    myPort = 21500

    s = socket(AF_INET, SOCK_STREAM) # create a TCP socket
    s.bind((myHost, myPort)) # bind it to the server port
    s.listen(5) # allow 5 simultaneous connections

    while True:
    connection, address = s.accept()
    while True:
    data = connection.recv(1024)
    if data:
    connection.send('echo -> ' + data)
    else:
    break
    connection.close() # close socket

    And a simple client:

    import sys
    from socket import *
    serverHost = 'localhost' # servername is localhost
    serverPort = 21500 # use arbitrary port > 1024

    s = socket(AF_INET, SOCK_STREAM) # create a TCP socket


    s.connect((serverHost, serverPort)) # connect to server on the port
    s.send('Hello world') # send the data
    data = s.recv(1024) # receive up to 1K bytes
    print(data)


    If I run testserver.py via the cmd prompt in Windows XP and then the
    testclient.py program, I get the following error:

    Traceback (most recent call last):
    File "C:\Python30\testclient.py", line 12, in <module>
    s.send('Hello world') # send the data
    TypeError: send() argument 1 must be string or buffer, not str

    This happens in 2.6 or 3.0 and with different example client & server
    programs from the web. What am I missing?

    Thanks,

    John R.
    , Dec 24, 2008
    #1
    1. Advertising

  2. En Wed, 24 Dec 2008 03:59:42 -0200,
    <> escribió:

    > New guy here. I'm trying to figure out sockets in order to one day do
    > a multiplayer game. Here's my problem: even the simplest examples
    > don't work on my computer:
    >
    > A simple server:
    >
    > from socket import *
    > myHost = ''


    Try with myHost = '127.0.0.1' instead - a firewall might be blocking your
    server.

    > s.listen(5) # allow 5 simultaneous connections


    Not exactly: your server program only handles a single connection at a
    time. The 5 above specifies how many connections may exist "on hold"
    waiting for you to accept() them.

    > connection.send('echo -> ' + data)


    That's fine for Python 2.6, but you must use b'echo -> ' with 3.0

    > And a simple client:
    >
    > s.send('Hello world') # send the data


    Same as above, should be b'Hello world' with Python 3.0

    > If I run testserver.py via the cmd prompt in Windows XP and then the
    > testclient.py program, I get the following error:
    >
    > Traceback (most recent call last):
    > File "C:\Python30\testclient.py", line 12, in <module>
    > s.send('Hello world') # send the data
    > TypeError: send() argument 1 must be string or buffer, not str


    The above error message is wrong (and I think it was corrected on the 3.0
    final release; if you got it with 3.0 final, file a bug report at
    http://bugs.python.org/ )

    > This happens in 2.6 or 3.0 and with different example client & server
    > programs from the web. What am I missing?


    The error above surely comes from 3.0; with 2.6 you should get a different
    error (if it fails at all). Try again with 2.6.1. I didn't run the code
    but it looks fine -- if you got it from a book or article, unless it
    explicitely says "Python 3.0", assume it was written for the 2.x series.

    --
    Gabriel Genellina
    Gabriel Genellina, Dec 24, 2008
    #2
    1. Advertising

  3. Guest

    Chris & Gabriel,

    Thank you so much. My simple example now works. It was very
    frustrating that even the simple example didn't work, so your help is
    most appreciated.

    b'hello world' was the key. As for the error, I do still get it with
    3.0 final so I'll go ahead and report it.

    John.

    On Dec 24, 12:03 am, "Gabriel Genellina" <>
    wrote:
    > En Wed, 24 Dec 2008 03:59:42 -0200,  
    > <> escribió:
    >
    > > New guy here.  I'm trying to figure out sockets in order to one day do
    > > a multiplayer game.  Here's my problem:  even the simplest examples
    > > don't work on my computer:

    >
    > > A simple server:

    >
    > > fromsocketimport *
    > > myHost = ''

    >
    > Try with myHost = '127.0.0.1' instead - a firewall might be blocking your  
    > server.
    >
    > > s.listen(5)                         # allow 5 simultaneous connections

    >
    > Not exactly: your server program only handles a single connection at a  
    > time. The 5 above specifies how many connections may exist "on hold"  
    > waiting for you to accept() them.
    >
    > >             connection.send('echo -> ' + data)

    >
    > That's fine for Python 2.6, but you must use b'echo -> ' with 3.0
    >
    > > And a simple client:

    >
    > > s.send('Hello world')               # send the data

    >
    > Same as above, should be b'Hello world' with Python 3.0
    >
    > > If I run testserver.py via the cmd prompt in Windows XP and then the
    > > testclient.py program, I get the following error:

    >
    > > Traceback (most recent call last):
    > >   File "C:\Python30\testclient.py", line 12, in <module>
    > >     s.send('Hello world')               # send the data
    > > TypeError: send() argument 1 must be string or buffer, not str

    >
    > The above error message is wrong (and I think it was corrected on the 3.0  
    > final release; if you got it with 3.0 final, file a bug report at  http://bugs.python.org/)
    >
    > > This happens in 2.6 or 3.0 and with different example client & server
    > > programs from the web.  What am I missing?

    >
    > The error above surely comes from 3.0; with 2.6 you should get a different  
    > error (if it fails at all). Try again with 2.6.1. I didn't run the code  
    > but it looks fine -- if you got it from a book or article, unless it  
    > explicitely says "Python 3.0", assume it was written for the 2.x series.
    >
    > --
    > Gabriel Genellina
    , Dec 25, 2008
    #3
  4. Guest

    Hi again,

    I've done some more playing around with socket and socketserver and
    have discovered I can send strings or lists with socket.send() by
    converting to bytes. But lists with strings in them or dicts can't be
    converted by bytes(). How can I send those?

    One idea I initially tried was to set up a server (host,port) for
    receiving data and another one (host, different port) for strings, but
    that didn't work so I was thinking of throwing everything into a list
    or a dictionary and sending that but that's not working either.

    Any ideas?

    Thanks,

    John.

    On Dec 24, 12:03 am, "Gabriel Genellina" <>
    wrote:
    > En Wed, 24 Dec 2008 03:59:42 -0200,  
    > <> escribió:
    >
    > > New guy here.  I'm trying to figure out sockets in order to one day do
    > > a multiplayer game.  Here's my problem:  even the simplest examples
    > > don't work on my computer:

    >
    > > A simple server:

    >
    > > fromsocketimport *
    > > myHost = ''

    >
    > Try with myHost = '127.0.0.1' instead - a firewall might be blocking your  
    > server.
    >
    > > s.listen(5)                         # allow 5 simultaneous connections

    >
    > Not exactly: your server program only handles a single connection at a  
    > time. The 5 above specifies how many connections may exist "on hold"  
    > waiting for you to accept() them.
    >
    > >             connection.send('echo -> ' + data)

    >
    > That's fine for Python 2.6, but you must use b'echo -> ' with 3.0
    >
    > > And a simple client:

    >
    > > s.send('Hello world')               # send the data

    >
    > Same as above, should be b'Hello world' with Python 3.0
    >
    > > If I run testserver.py via the cmd prompt in Windows XP and then the
    > > testclient.py program, I get the following error:

    >
    > > Traceback (most recent call last):
    > >   File "C:\Python30\testclient.py", line 12, in <module>
    > >     s.send('Hello world')               # send the data
    > > TypeError: send() argument 1 must be string or buffer, not str

    >
    > The above error message is wrong (and I think it was corrected on the 3.0  
    > final release; if you got it with 3.0 final, file a bug report at  http://bugs.python.org/)
    >
    > > This happens in 2.6 or 3.0 and with different example client & server
    > > programs from the web.  What am I missing?

    >
    > The error above surely comes from 3.0; with 2.6 you should get a different  
    > error (if it fails at all). Try again with 2.6.1. I didn't run the code  
    > but it looks fine -- if you got it from a book or article, unless it  
    > explicitely says "Python 3.0", assume it was written for the 2.x series.
    >
    > --
    > Gabriel Genellina
    , Dec 26, 2008
    #4
  5. Chris Rebert Guest

    On Thu, Dec 25, 2008 at 10:08 PM, <> wrote:
    > Hi again,
    >
    > I've done some more playing around with socket and socketserver and
    > have discovered I can send strings or lists with socket.send() by
    > converting to bytes. But lists with strings in them or dicts can't be
    > converted by bytes(). How can I send those?


    If you're sending structured data rather than just bytestrings, you
    should use proper serialization. Use the `json`, `pickle`, or
    `marshal` modules to convert your data to an external representation
    in bytes, send the bytes thru the socket, then deserialize the bytes
    back into data structures using the same module again.
    The Python std lib docs are your friend.

    Merry Christmas,
    Chris

    --
    Follow the path of the Iguana...
    http://rebertia.com
    Chris Rebert, Dec 26, 2008
    #5
  6. Bryan Olson Guest

    Gabriel Genellina wrote:
    > escribió:

    [...]
    >> A simple server:
    >>
    >> from socket import *
    >> myHost = ''

    >
    > Try with myHost = '127.0.0.1' instead - a firewall might be blocking
    > your server.


    Just a nit: I'd say the reason to use '127.0.0.1' instead of the empty
    string is that a firewall might *not* be blocking your server.

    The Python sockets module interprets the empty string as INADDR_ANY,
    which means to bind to all available adapters including the loopback,
    A.K.A localhost, A.K.A '127.0.0.1'.


    --
    --Bryan
    Bryan Olson, Jan 3, 2009
    #6
  7. En Sat, 03 Jan 2009 21:44:34 -0200, Bryan Olson <>
    escribió:

    > Gabriel Genellina wrote:
    >> escribió:

    > [...]
    >>> A simple server:
    >>>
    >>> from socket import *
    >>> myHost = ''

    >> Try with myHost = '127.0.0.1' instead - a firewall might be blocking
    >> your server.

    >
    > Just a nit: I'd say the reason to use '127.0.0.1' instead of the empty
    > string is that a firewall might *not* be blocking your server.
    >
    > The Python sockets module interprets the empty string as INADDR_ANY,
    > which means to bind to all available adapters including the loopback,
    > A.K.A localhost, A.K.A '127.0.0.1'.


    I thought a firewall would block an attempt to bind to any routeable
    address, but not to localhost. So using INADDR_ANY would be rejected.

    --
    Gabriel Genellina
    Gabriel Genellina, Jan 5, 2009
    #7
  8. Bryan Olson Guest

    Gabriel Genellina wrote:
    > Bryan Olson escribió:
    >
    >> Gabriel Genellina wrote:
    >>> escribió:

    >> [...]
    >>>> A simple server:
    >>>>
    >>>> from socket import *
    >>>> myHost = ''
    >>> Try with myHost = '127.0.0.1' instead - a firewall might be blocking
    >>> your server.

    >>
    >> Just a nit: I'd say the reason to use '127.0.0.1' instead of the empty
    >> string is that a firewall might *not* be blocking your server.
    >>
    >> The Python sockets module interprets the empty string as INADDR_ANY,
    >> which means to bind to all available adapters including the loopback,
    >> A.K.A localhost, A.K.A '127.0.0.1'.

    >
    > I thought a firewall would block an attempt to bind to any routeable
    > address, but not to localhost. So using INADDR_ANY would be rejected.


    So you thought this would fail at bind()?

    My understanding is that firewalls block network traffic, not system calls.


    --
    --Bryan
    Bryan Olson, Jan 6, 2009
    #8
  9. James Mills Guest

    On Tue, Jan 6, 2009 at 10:49 AM, Bryan Olson <> wrote:
    >> I thought a firewall would block an attempt to bind to any routeable
    >> address, but not to localhost. So using INADDR_ANY would be rejected.


    No.

    > My understanding is that firewalls block network traffic, not system calls.


    This is correct. Firewalls (real firewalls) can only act on incoming
    and outgoing traffic on the IP level.

    cheers
    James
    James Mills, Jan 6, 2009
    #9
  10. James Mills Guest

    On Wed, Dec 24, 2008 at 3:59 PM, <> wrote:
    (snip)

    > If I run testserver.py via the cmd prompt in Windows XP and then the
    > testclient.py program, I get the following error:
    >
    > Traceback (most recent call last):
    > File "C:\Python30\testclient.py", line 12, in <module>
    > s.send('Hello world') # send the data
    > TypeError: send() argument 1 must be string or buffer, not str
    >
    > This happens in 2.6 or 3.0 and with different example client & server
    > programs from the web. What am I missing?


    I'm sorry I should have answered sooner :)
    Python 3.x (and probably 2.6+) required that you use
    bytes to send your data through sockets rather than
    strings. This was part of the revamp for better unicode
    support irrc.

    cheers
    James
    James Mills, Jan 6, 2009
    #10
  11. En Mon, 05 Jan 2009 22:59:46 -0200, James Mills
    <> escribió:
    > On Tue, Jan 6, 2009 at 10:49 AM, Bryan Olson <>
    > wrote:
    >>> I thought a firewall would block an attempt to bind to any routeable
    >>> address, but not to localhost. So using INADDR_ANY would be rejected.

    >
    > No.
    >
    >> My understanding is that firewalls block network traffic, not system
    >> calls.

    >
    > This is correct. Firewalls (real firewalls) can only act on incoming
    > and outgoing traffic on the IP level.


    That's true for hardware firewalls (those found in a router, by example).
    They can at most analyze traffic at the application layer but have no idea
    of the applications (processes) behind.
    A "software firewall" may react not just to traffic but to *who* is doing
    that; it may block *processes* when they try to bind/listen to any port,
    even before any packet is sent or received. See
    http://www.securityfocus.com/infocus/1839
    (One may argue whether those are *real* firewalls or not, but that's their
    common name...)
    (Also note that I'm far for being an expert on these topics)

    --
    Gabriel Genellina
    Gabriel Genellina, Jan 6, 2009
    #11
  12. Bryan Olson Guest

    Gabriel Genellina wrote:
    > James Mills escribió:
    >> Bryan Olson wrote:
    >>>> I thought a firewall would block an attempt to bind to any routeable
    >>>> address, but not to localhost. So using INADDR_ANY would be rejected.

    >>
    >> No.
    >>
    >>> My understanding is that firewalls block network traffic, not system
    >>> calls.

    >>
    >> This is correct. Firewalls (real firewalls) can only act on incoming
    >> and outgoing traffic on the IP level.

    >
    > That's true for hardware firewalls (those found in a router, by
    > example). They can at most analyze traffic at the application layer but
    > have no idea of the applications (processes) behind.
    > A "software firewall" may react not just to traffic but to *who* is
    > doing that; it may block *processes* when they try to bind/listen to any
    > port, even before any packet is sent or received. See
    > http://www.securityfocus.com/infocus/1839
    > (One may argue whether those are *real* firewalls or not, but that's
    > their common name...)


    Even if one's 'firewall' product is one of "the rather useless ones that
    merely hook socket calls" (in the words of the linked article), I still
    don't see failing a bind() to INADDR_ANY while allowing a bind() to
    127.0.0.1. INADDR_ANY means all available adapters. If some physical
    network adapter should be unavailable while the loopback is allowed,
    fine; passing INADDR_ANY should work and bind to the loopback adapter.

    > (Also note that I'm far for being an expert on these topics)


    Sure. I was mostly just making a couple points because at one time they
    confused me. Python's socket.bind() treats the empty string as
    INADDR_ANY, which means all available adapters. It's a fine address
    parameter for bind(), and ought to work at least as well as any. The
    time to bind() to localhost is when we specifically do not want to be
    available on an external network adapter.

    Now don't get me started on the vagaries of passing INADDR_ANY to connect().

    --
    --Bryan
    Bryan Olson, Jan 7, 2009
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Reay

    Does Socket.send send all bytes?

    Chris Reay, Nov 3, 2003, in forum: Ruby
    Replies:
    2
    Views:
    218
    Chris Reay
    Nov 4, 2003
  2. Ryan Parmeter
    Replies:
    4
    Views:
    245
    Douglas Wells
    Sep 5, 2007
  3. Thomas Rachel
    Replies:
    0
    Views:
    199
    Thomas Rachel
    Jan 7, 2013
  4. Steven D'Aprano
    Replies:
    1
    Views:
    123
    Chris Angelico
    Jan 7, 2013
  5. Philipp Hagemeister
    Replies:
    0
    Views:
    153
    Philipp Hagemeister
    Jan 8, 2013
Loading...

Share This Page