It is supposed to receive from a tcp socket a 2 line string but in fact i am receiving only the string until the new line.
socket = socket(AF_INET,SOCK_STREAM)
socket.connect((ip,port))
data = socket.recv(1024)
print "%s" % data
if a call the receive function now it will receive the second part of the string after the break line.This is not what i want in fact. It should return the entire string from the first call. When i use nc to connect to the server i am receiving the string normally in the beginning of the connection.Why that happens?
Because TCP is a streaming protocol (as indicated by the SOCK_STREAM
) there are no fixed message boundaries or packets, and you can never be sure you get everything with just one call to recv
. You simply have to call recv
in a loop, adding to a buffer, and exit the loop when you deem that you have enough. Most text-only protocols use either newline to tell that the read is done and to do something with the received data. Other protocols use other characters, or byte sequences.
In your case, if there is no special character saying that the end of the current data has been reached, you have two solutions:
Use a timeout: When no new data has been received for some time, print it.
Non-blocking sockets: Simply read in a loop, appending data to an internal buffer. When the call to recv
throws an error with errno
equal to errno.EWOULDBLOCK
, then there is no more to read for now and print the received data.
Alternative 2, together with the package select
, is probably the best way to go.
Here is a simple example of what I mean. It will probably not work like this, and will need some tweaking, but hopefully it's enough for you to build on.
# Need to import: package socket, package select, package errno
# Create socket and connect to server
# Make the socket non-blocking (see http://docs.python.org/library/socket.html#socket.socket.setblocking)
socket.setblocking(0)
run_main_loop = True
while run_main_loop:
# Wait for events...
read_ready, _, _ = select.select([socket], None, None)
if socket in read_ready:
# The socket have data ready to be received
buffer = ''
continue_recv = True
while continue_recv:
try:
# Try to receive som data
buffer += socket.recv(1024)
except socket.error, e:
if e.errno != errno.EWOULDBLOCK:
# Error! Print it and tell main loop to stop
print 'Error: %r' % e
run_main_loop = False
# If e.errno is errno.EWOULDBLOCK, then no more data
continue_recv = False
# We now have all data we can in "buffer"
print '%r' % buffer
socket.close()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With