socket send help

G

greywine

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

Gabriel Genellina

En Wed, 24 Dec 2008 03:59:42 -0200, (e-mail address removed)
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.
 
G

greywine

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

greywine

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

Chris Rebert

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
 
B

Bryan Olson

Gabriel said:
(e-mail address removed) 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'.
 
G

Gabriel Genellina

Gabriel said:
(e-mail address removed) 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.
 
B

Bryan Olson

Gabriel said:
Bryan Olson escribió:
Gabriel said:
(e-mail address removed) 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.
 
J

James Mills

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
 
J

James Mills

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
 
G

Gabriel Genellina

En Mon, 05 Jan 2009 22:59:46 -0200, James Mills
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)
 
B

Bryan Olson

Gabriel said:
James Mills escribió:

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().
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top