sending very large packets over the network

Azazello tylerca at jeld-wen.com
Thu Aug 2 11:27:42 EDT 2007


On Aug 1, 8:50 pm, Gary Herron <gher... at islandtraining.com> wrote:
> Walker Lindley wrote:
> > OK, I'm back with another networking question. I'm trying to seend
> > large amounts of information over TCP (the length of data being given
> > to send() is on the order of 16000 characters in length).
> > Unfortunately on the receiving end, the packets appear to be
> > truncated. So I wrote some code that continuously tries to send bigger
> > and bigger packets until it fails and noticed that it never fails at
> > the same length. I'm not even sure these two things are related, but
> > is there some undocumented (or documented and I missed it) maximum
> > size for data you can pass to send()?
>
> For ethernet connections the size is often about 1500.  But the size
> depends on the underlying protocol, and even if you know the underlying
> protocol along the full route, you can't rely on packets that are
> received being the same as those that are sent.
>
> TCP/IP is a *stream* connection.  What you are guaranteed is this:  All
> the bytes that are sent from one end will be received eventually on the
> other end, in the proper order.  (Or failing that, you will receive an
> error notification.)  No guarantee is made about the packet sizes on
> either end, and you can't even rely on the packets being the same in
> number or length on the two ends.
>
> Your send code can try sending a packet of any size, but it must be
> prepared to examine the number of bytes actually sent, and retry with
> the remainder in a loop until all bytes are sent.    Similarly your
> receiving code must loop around the receive accepting whatever sized
> packets makes it through the connection.
>
> In many TCP/IP connections, it seems that the packets received are
> one-for-one with the packets sent, but relying on this *IS AN ERROR*
> that will bite you.  It fails to across the internet (sometimes) and
> when (at least some) wireless cards are involved.
>
> You may be better off using a package that knows all this and handles it
> properly.  Modules asyncore and asynchat are one possibility.
>
> Gary Herron
>
>
>
>
>
> > the sample code is as follows
> > #server
> > import socket
>
> > s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> > s.bind(("", 2000))
> > s.listen(0)
> > sock, addrinfo = s.accept()
> > for i in range(2 ** 16):
> >  length = int(sock.recv(16))
> >  print "excpecting data of length:", length
> >  data = sock.recv(length)
> >  print "received data of length:", len(data)
> >  print
> > s.close()
> > sock.close()
>
> > #client
> > import socket
> > import time
>
> > s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> > s.bind(("", 2001))
> > s.connect(("localhost", 2000))
> > for i in range(2 ** 16):
> >  packet = "h" * i
> >  s.send("%16d" % len(packet))
> >  print "attempting to send data of length:", len(packet)
> >  tmp = s.send(packet)
> >  print "actually sent data of length:", tmp
> >  print
> >  time.sleep(.001)
> > s.close()
>
> > i just put them in different files and ran them from the command line.
> > Any help or suggestions would be greatly appreciated. Thanks.
>
> > -Walker
>
> > --
> > This e-mail is licensed under the Creative Commons
> > Attribution-NoDerivs 2.5 License. To view a copy of this license,
> > visithttp://creativecommons.org/licenses/by-nd/2.5/or send a letter
> > to Creative Commons, 543 Howard Street, 5th Floor, San Francisco,
> > California, 94105, USA.- Hide quoted text -
>
> - Show quoted text -

I'm not an expert on networking so take my advice with a grain of
salt!

My guess is that you're encountering race-like conditions between the
send and recv. commmands because you're running your communication
command 2^16 times, hoping that send and recv. are synchronous on
every step.  This is especially true when you're running other
commands in your data sending loops! Prints take quite a lot of time.
Also, the send command in C (i'm not sure if this is true in python)
does not guarantee that all of your data gets out.

I'm assuming that you're somewhat new to networking so I would
recommend shying away from running an Asynchronous polling server.
Although it is probably a better way to do this.

My suggestions:

Write a while loop in the server with some end of stream checking,
timeouts, et cetera. This will give you a bit of flexibility and
feedback when things go to pot.  Use the sendall() command  in your
client because it throws an exception if data isn't properly sent. and
will eliminate a unsightly for loop.

Client

socket.sendall(data)

Something akin to this old piece of test code

datastream = ''

## A timeout exception is thrown if the receiver is waiting on the
line for .25 seconds
socket.settimeout(.25)

    while 1:
	try:
            buf = socket.recv(1024) ## If data on line put in buffer
        except socket.timeout:      ## Data buffer timeout,  breaks
while loop
            break
	if buf == '': ## If an empty buffer, jump to top of loop (beginning
of file check)
	    continue

        datastream = datastream + str(buf)

        if not len(buf) == 1024:  ## If the buffer is not full break
signaling end of file.
            break

Hope this helps!  And like i said i'm pretty new to this so be
careful!  Foundations of Network Programming by John Goerzen is a
great book if you want some good information on the topic.

Tyler




More information about the Python-list mailing list