socket bug or not?

G

Gabriel Rossetti

Hello everyone,

I found what was not working in my code (see Twisted mailing list topics
"self.socket.accept() in doRead() in tcp.py has (11, 'Resource
temporarily unavailable') error", "Twisted, PushProducer, Words & big
msgs, any limit?" and Python mailing list topic "socket.send : (11,
'Resource temporarily unavailable')"). I was just wondering if this was
a bug or not, so here it is, I wrote aserver using twisted words'
xmlstream class. When a client connects, it sends "<stream>" and the
server also sends it, so a bi-directional xmlstream communication is
established. This works fine, I at some point wrote a webservice to send
msgs to my system, not using any twisted code, that sends a message to
my server in this format : "<stream><message>.....</message></stream>".
This worked fine as long as the messages were small, but if it send
larger msgs (I tried +128k msgs) the server only received part of the
msg and then the parser died because of this, so my msg appeared to be
dropped. I discovered that it was because my webservice did not read the
"<stream>" element sent by the server when it connected (since I was not
interested in having a bidirectional xml stream communication with it),
when I added the code to read it, everything worked as expected. I
tested the webservice to without the server to see if it had a problem,
using netcat, and it does, so I wonder if there is a bug in the socket
code or not. Here is the test code :


###################### Listing 1 Start ######################
import socket, time
STREAM_START = "<stream>"
STREAM_END = "</stream>"

def sendTestMessage(host, port):
msg = "<message>" + ('a' * 175177) + "</message>"
burstSize = 4096
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(STREAM_START)
time.sleep(5)
while msg:
sent = sock.send(msg[:burstSize])
print "Sending %d bytes..." % sent
if sent == 0:
raise RuntimeError, "socket connection broken"
msg = msg[burstSize:]
sock.send(STREAM_END)
sock.close()
###################### Listing 1 End ######################

To test it:

1) open a python interpretor, copy-past the code above
2) open another terminal and run netcat using the following command :
nc -v -l -p 4444
3) call the above function using : sendTestMessage("localhost", 4444),
it will wait 5 seconds after having sent the <stream>, for the first
test, just wait.

The message will be completely send and received by the netcat "server",
now let's test the case I have, where the server sends a <stream>, to do
that, repeat the above steps (you have to re-run netcat as it exits when
the client disconnects), except in step 3 instead of just waiting, type
<stream> and press enter in the netcat terminal after having received
the <stream> element from the sending code. This time you will see that
the message is incomplete.

If you send a smaller message, like by replacing the following line :

msg = "<message>" + ('a' * 175177) + "</message>"

with :

msg = "<message>" + ('a' * (175177/4)) + "</message>"

it works in both cases.

Now test the "fixed" code :

###################### Listing 2 Start ######################
import socket
STREAM_START = "<stream>"
STREAM_END = "</stream>"

def sendTestMessage(host, port):
msg = "<message>" + ('a' * 175177) + "</message>"
burstSize = 4096
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
sock.send(STREAM_START)
sock.recv(len(STREAM_START)+1)
while msg:
sent = sock.send(msg[:burstSize])
print "Sending %d bytes..." % sent
if sent == 0:
raise RuntimeError, "socket connection broken"
msg = msg[burstSize:]
sock.send(STREAM_END)
sock.close()
###################### Listing 2 End ######################

This time the code reads for the <stream> element after sending the
<stream> element so it works, just try the steps described above, the
ones where you have to type <stream> and press enter in the netcat
terminal and this time it works.

Is this a bug in the sockets code, or is this normal? If it's normal I
think it should be mentioned somewhere. Oh, by the way, I use linux and
this code was tested only on linux, I don't know if the problem also
occurs on other platforms.

Gabriel
 

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,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top