Recv Over Sockets in Python
by oBelIX
EDIT: I wrote this many years ago. There are much better ways of doing this. Please please please, go lookup them up on the internet. Or ask on stackoverflow. If you do what I’ve done it’s going to bite you in the behind.
I finally figured it out. How do you get an arbitrary length of data no matter what in python over sockets?
The problem is this. Suppose you have a connected socket between two machines A and B.
Suppose A does socketA.sendall(<some long string>). Now how does B recv all the data.
If B does socketB.recv(1024) its going to possibly get the first packet that was sent. B does not know how long it has to wait or how much data there is. The simplest solution is for A to attach the length of the data as in socketA.sendall(str(len(<data>)) + <data>)
A better way, ladies and gentlemen (Yes, this seemingly obvious bit of code finally struck after 4 years of programming in python) and it is applicable across any language
def getDataFromSocket(sck):
data = “”
sck.settimeout(None)
data = sck.recv(1024)
sck.settimeout(2)while 1:
line = “”
try:
line = sck.recv(1024)
except socket.timeout:
breakif line == “”:
breakdata += line
return data
Yes. You may all thank me now.
shouldn’t python by definition be pretty long by itself ??? 😛
you still use python :-O i think you should be using something like “visual” python by this time 😛 anyway thanks for the script 🙂
😛
sucketh programming 😛
@mythalez and sreejith: very droll …
@bordeaux: python rocks, its used everywhere
@obelix
i know python rocks … but you should have made it visual by this time .. you are in m$ since one long year 😛
was reminded of this post as i read this.. http://xkcd.com/353/
http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython
I think the socket.timeout should be replaced by socket.dynmulpath .. stands for an automated timedout due to asynchronous dynamic multipathing owing to some packet switching by djikstra’s second theorem .
PS : Post the 10H type posts not these techie posts 😀
Sorry to resurrect an old blog post but you could just end the data with “\n”
and read 1by1 until the end
[CODE]
dat = “”
while 1:
char = self.sock.recv(1)
if char == “\n”: return dat
else: dat=dat+char
[/CODE]
I think it’s a bit slowly.
every time we should wait 2s.
sometimes the easiest things are the hardest to get. Thanks for this share.
That code is amazing!!! 😉
This is terrible code! Just because two seconds pass doesn’t mean you’ve received all of the data. In most cases two seconds is way too long and this code will run terribly slowly; but when a network glitch does strike it may well last longer than two seconds and you’ll have an incomplete message! So, first, this is broken and won’t work; and, second, it’s really slow brokenness. Watching for an end-of-message delimiter or prefixing each message with a length are the only ways to be sure you’ve received all of the client’s data — and usually takes vastly less time than two seconds anyway.
@Brandon Craig Rhodes: Full Ack! Nobody should ever use this code. It’s an absolutely terrible and unclean hack, which will not work correctly. I’m sure, it will fail at least one of ten times.
A school example of how NOT to do it! Please remove or edit the post before somebody uses that code. As Brandon mentions, the right way to do this is either end-of-message delimiter or include a length prefix.