Skip to content Skip to sidebar Skip to footer

Why Is This Input Being Over Lapped By Another Input?

I have made a TCP Server in Python 2.7.10 and once I input my username it is meant to ask for the password but instead of saying Username: Admin Password: Admin it says Username

Solution 1:

You don't show what is happening on the other end of the connection. However, I'm pretty sure the problem is that you are not properly distinguishing the boundaries of the different messages you receive. For example, let's say one side executes this:

s.send('Hello')
s.send('Again')
s.send('Once More')

While the other side executes:

first = s.recv(512)
second = s.recv(512)
third = s.recv(512)

What is quite likely to happen here is that the first recv will receive all three chunks of data ('HelloAgainOnce More'), and the receiving side will then hang on the second recv waiting for the sending system to send more data. But note that it's also possible -- and valid according to the socket API -- that the first recv gets 'Hel', the second recv gets 'l' and the third gets 'o' and the remaining bytes are left in transit somewhere (eventually queued in the receiving system's kernel buffers). There are a number of other possible outcomes too.

The point here is that you must provide your own message boundaries when using TCP stream sockets. TCP delivers a stream of data from one peer to the other. Any boundaries the application intends are not guaranteed to be respected by recv calls and often will not be.

There are two usual ways of distinguishing message boundaries:

  1. For "text-based" protocols, some separator -- such as a newline or a null byte -- separates messages. Protocols like HTTP use this. In python, this is typically done by first recving data into a buffer and then pulling out bits of it until you find the message separator (going back to recv more if you don't find the separator).

  2. For binary protocols, the protocol provides explicit length fields for each chunk of data. In python, this often involves the use of the struct module, which allows you to construct binary fields containing integer and other numeric values in particular sizes. Then receiving messages of (or consuming from a buffer) an exact number of bytes at a time (again going back to recv more until you obtain all the bytes you need for a given message).

(I should mention that it is technically also possible that the send does not send its entire argument: there are cases where, when you execute s.send('Hello'), only 'H' gets sent. You can remedy that by using the sendall method which simply continues the send until all parts of the provided data have been transmitted.)

Post a Comment for "Why Is This Input Being Over Lapped By Another Input?"