Re: sending very large packets over the network



On Aug 1, 8:50 pm, Gary Herron <gher...@xxxxxxxxxxxxxxxxxx> 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

.



Relevant Pages

  • Re: Determining if it is "safe" to send UDP packets
    ... for receiving Udp data. ... I'm receiving from a camera lines of data at 55 Hz. ... I had to build some test programs that sent & received packets. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: The best way to wait for something to happen
    ... Be careful of UDP connections. ... packets, and then reordering them once they have all arrived. ... What do you recommend that would allow applications running on a LAN to ... I am coding a form that will be sending and receiving TCP/IP ...
    (microsoft.public.fox.programmer.exchange)
  • Re: Winsock - how to insure packets are received?
    ... The number of packets sent is not guaranteed to ... The receiving end needs to be able to parse the incoming data and buffer ... If I iterate 1000 times from the client to the server on my local machine ...
    (microsoft.public.vb.general.discussion)
  • Re: Streaming Video across the IT
    ... for most users there won't be any satellite hops in Internet streaming. ... With Internet, packets are sent, not in a contimuous stream and not ... This is why on receiving the "packets" ... need to "sorted" and joined to give reliable video. ...
    (comp.sys.mac.apps)
  • Error i dont understand
    ... I have created a form with 5 option groups. ... I then added a command button. ... communicating with the OLE server or ActiveX Control." ... the message, I even commented the code out, but I am still receiving the ...
    (microsoft.public.access.formscoding)