Though not technically a part of the MSN Messenger protocol, a file transfer protocol called "MSNFTP" is included in the official client. This protocol is unrelated to "FTP", or any other file transfer protocol.
Several very similar terms are used in MSNFTP, which can be make it very confusing to read this page. The "sender" and "receiver" is the computer which sends and receives the file, respectively. The "server" and "client" is the computer which initiates and receives the TCP connection, respectively. A messages is "transmitted" (so as not to confuse "sending a message" with "sending the file").
During the invitation stage, the messenger clients will agree on which computer should be the server and which the client, which computer should be sender and which the receiver, what the file to be transferred is called, and an authentication cookie for the session. The sender is usually the server, but may ask the receiver to serve.
Once the client has connected to the server, MSNFTP begins with the two computers exchanging lines of text much like in an NS or SB conversation. In this initial stage, the computers negotiate a protocol, the receiver gives its passport and the authentication cookie, and the sender replies with the size of the file. Then, the sender sends the file in fixed-length blocks of binary data. The receiver can cancel the transfer at any time.
During the invitation stage, the computers agreed on either one or two IP addresses and ports the client should connect to. If only one IP address and port was given, the client should connect to that address and port, while the server should listen for connections on the port. If two addresses and ports were given, the server should listen for connections on both ports, while the client should simultaneously attempt to connect to the primary and secondary IP addresses and ports. As soon as one connection has been established, both computers should stop attempting to connect on the other port.
This section discusses binary data, how to transmit and receive it. If you're already familiar with binary, you can safely ignore this section.
Ultimately, all computer information is just a series of 1s and 0s. A byte is a series of eight 1s and 0s, so a byte can be in any one of 256 (2^8) different states. In a text-based protocol like MSN Messenger, bytes are interpreted as characters of information according to some standard - usually ASCII. In a binary protocol, bytes are interpreted as something else - numbers between 0 and 255, shades of grey between black and white, reasons for a program crashing, etc.
It's most popular to interpret bytes of data as numbers, often in base 16 ("hexadecimal") instead of base 10 ("decimal"). To make this page easier to read, I'll use decimal, but hexadecimal numbers are used a lot in computing - for example, in plaintext message colour codes. Some programmers like to write things in hexadecimal because (once you get used to it) it's much easier to convert between hexadecimal and binary in your head.
You should consult your language's documentation about how it handles binary data. One important thing to check is that many programming languages (e.g. C and Visual Basic) use the same data type to represent a byte that they use to represent a character, but don't treat bytes and characters the same way - for example, the character '0' is not the same as the number 0. In Visual Basic, for example, you have to do asc(0) to get the ASCII character equivalent to the number 0, and val('0') to get the numerical value of the ASCII character 0.
The text section resembles the authentication step of logging into a notification server, except that there are no transaction IDs, and if either side transmits an invalid command, the other side should just close the connection without transmitting an error message.
First, the receiver transmits a VER
command with the versions of the MSNFTP protocol it supports as parameters. The official client only supports MSNFTP
. The sender replies with a VER
command containing the chosen protocol.
Then, the receiver transmits a USR
command with the username as the first parameter and authentication cookie as the second. The sender replies with a FIL
command with the size of the file in bytes as the only parameter. The official client uses this instead of the size given during the invitation stage.
The receiver transmits a TFR
command to indicate that it is ready to receive. At this point, the sender switches to binary for the rest of the session.
At some point after that, the receiver must transmit BYE
with a single numeric argument indicating the result of the file transfer. The following values are allowed:
As a special case, CCL
should be sent with no argument instead of BYE 2164261682
. In practice, only BYE 16777989
and CCL
have ever been observed, and the official client's support for other codes is shabby at best.
Once the sender has finished sending, it should wait for the receiver to transmit a BYE
command. If the sender does not receive a BYE
quickly enough (within about 1 minute in the official client), it will transmit an invitation command in the switchboard session with "Invitation-Command: CANCEL" and "Cancel-Code: FTTIMEOUT". The sender may close the connection at any time after it has finished sending.
An MSNFTP block consists of a header and a body. The header specifies whether the file has been completely sent, and (if not) the number of bytes that will be sent in the body of this block. The body contains the specified number of bytes from the file.
The header is three bytes long. If the file has not been completely transmitted, the first byte of the header will be 0, and the second two bytes of the header will specify the length of the body - the length is equal to the value of the second byte plus 256 times the value of the third byte. So, for example, if the number of bytes in the body is 2045 (the default length in the official client), the value of second byte would be 253 and the value of the third byte would be 7 (253 + 7*256 = 2045). the specified number of bytes follow in the body. Once the file has been completely transmitted, a final block is sent in which the first byte of the header is 1, the second two bytes are 0, and the body is empty.
For example, if you wanted to transmit a 13-byte long file containing the string "Hello, world!", the steps you might go through are:
BYE
or CCL
message. If so, close the socket.BYE
or CCL
, then close the connectionHere is an example of a successful transfer (note that italics represent binary data):
<o> Incoming Connection on Port: 6891
<<< VER MYPROTO MSNFTP
>>> VER MSNFTP
<<< USR myname@msn.com 93301
>>> FIL 13
<<< TFR
>>> 0, 13, 0, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33
>>> 1, 0, 0
<<< BYE 16777989
And here is a failed negotiation:
<o> Incoming Connection on Port: 6891
<<< VER MYPROTO
<o> Disconnect