Click here to Skip to main content
15,879,326 members
Articles / Programming Languages / C#
Article

Connecting to MSN messenger with the MSNP9 protocol

Rate me:
Please Sign up or sign in to vote.
4.34/5 (34 votes)
4 Nov 20035 min read 507.2K   1.2K   103   56
This article explains how you can connect to MSN using the MSNP9 protocol. It also refers to another article I wrote.

Introduction

MSN messenger is a well known program. It lets you communicate with other users through Instant Messaging. Some people like to write their own MSN messenger, so that they can make some own adjustments and cool features. I have written, together with another student, our own MSN client in C#.  Recently Microsoft no longer supported protocols below MSNP 8. So I had to adjust our program to use MSNP9 (it used MSNP7).

After I have posted an earlier article about MSN, people asked me to give some more information on how to connect to the MSN servers.

So with this little article I would like to explain how you can connect to MSN with the use of the MSNP9 protocol. This article tells you what commands you have to send, and how to react to it. It uses an article that I have posted before. You can find it here.

Using the code

You can use this code in your own program, or you can look and see how you can connect to MSN in C#. The demo programs shows how you can use the following code.

What do we need?

First we use a separate class that will connect to the MSN server. We call it MSNConnection. Next we build another class that handles the commands that we receive from the servers, lets call this class ServerCommand.

Next we need to declare some variables that we will use in the class MSNConnection.

C#
private long            _transactionID = 0;
private TcpClient       _socket;
private NetworkStream   _stream;
private StreamReader    _reader;
private StreamWriter    _writer;

The transactionID is sent with almost every message that we send (also in chat sessions). The _reader and _writer are the streams from the socket.

Now we have the above, let's define some functions that will do the work for us. First we need to initialize the socket and StreamReaders.

C#
_transactionID = 0;
_socket = new TcpClient(host, port);
_stream = _socket.GetStream();
_reader = new StreamReader(_stream, Encoding.ASCII);
_writer = new StreamWriter(_stream, Encoding.ASCII);
_writer.AutoFlush = true;

We call this function ConnectSocket and it takes two parameters (host and port). Every time we make a new connection the transactionId is set to zero. If we make a function that creates the socket, why not make a function that closes the socket. Let's call it dispose.

C#
if( _socket != null )
{
    _reader.Close();
    _writer.Close();
    _stream.Close();
    _socket.Close();
    _socket = null;
}

We are making functions that read and write to the StreamReader and StreamWriter. First we define the StreamWriter. We then make a function that builds the string: WriteCommand. It takes 3 parameters: first is the command to send, next the parameters and last the option to leave the transactionId out.

C#
string line;
// check what type of format it should be
if (bSendId) 
    line = string.Format("{0} {1} {2}", command, _transactionID, parameters);
else
    line = string.Format("{0} {1}", command, parameters);
// Write the line
WriteLine(line, true);

The function WriteLine eventually writes the string to the StreamWriter. This function has two parameters first is the entire string and next is the option to send only a string and no end character.

C#
if (writeNewLine)
    _writer.WriteLine(line);
else
    _writer.Write(line);
// raise the transactionId
_transactionID++;

We have defined some writing functions. We also need to read the information. Let's call this function ReadCommand. This function reads from the reader, if there is nothing in the socket then makes an empty ServerCommand, else we make a ServerCommand with the given response.

C#
string  line = _reader.ReadLine();
Console.WriteLine("Reading: " + line);
if (line == null) 
{
    Console.WriteLine("Nothing received");
    return new ServerCommand();
}
else
{
    return new ServerCommand(line);
}

You noticed that I use the ServerCommand object. Lets look at the ServerCommand class.

C#
private string _cmdID;
private string _line;
private string[] _params;

public ServerCommand(string line)
{
    _line = line;
    // always 3 characters command
    _cmdID = line.Substring(0, 3);
    if (!(_cmdID == "QNG"))
    {
        _params = line.Substring(4).Split(' ');
    }
}

public ServerCommand()
{
    _line = "";
    _cmdID = "ERROR";
}

If we use the constructor with a valid line, then we will get a ServerCommand with the right information. If we get a QNG command then there will be no parameters. The command is always a three letter combination. If we use the constructor with no string, then the program knows that there is something wrong.

The other functions are used for retrieving the data from this class.

C#
public string CommandName
{
    get { return _cmdID; }
}

public string Param(int index)
{
    return _params[index];
}

Now all the functions are explained above, we can make the Connect function. This function needs two parameters: first is a valid username that has a passport, next is the password for that username.

First we are going to connect to the server.

C#
string  host = "messenger.hotmail.com"; 
int port = 1863;

ConnectSocket(host, port);

Now we are going to write the server commands, the first command we are going to write is the VER command. This command indicates what protocol we are using. We are using protocol MSNP9. We read the result in a new ServerCommand Object.

C#
ServerCommand ServCom

WriteCommand("VER", "MSNP9 CVRO", true); 
ServCom = ReadCommand();

Next we are going to check if we received the right information, if not then exit this function.

C#
if (ServCom.CommandName != "VER")
{
    return 1;
}

Now we have to send the CVR command, the parameters are the same like a real MSN messenger client. The server will response with a CVR command and a download place where you can get a newer MSN messenger, we just ignore this.

C#
WriteCommand("CVR", 
  "0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS " + UserName, true);
ServCom = ReadCommand(); 

After this is successful, we send de USR command with a TWN parameter and your username. TWN stands for TWEENER, this is based on the passport authentication.

C#
WriteCommand("USR", "TWN I " + UserName, true);
ServCom = ReadCommand();

If the command was not the USR command, it was probably the XFR command, this indicates to us that we have to transfer to another server. In the result is the new host and port, parse it.

C#
string[] arIP = ServCom.Param(2).Split(':');
host = arIP[0];
port = int.Parse(arIP[1]);

Now disconnect and connect again using the new host and port.

Dispose();

We were operating in a while loop, so the connect sequence starts again. You have to send all the commands again, but this time it is to another server.

If the responsecommand is USR then we are going to connect to this server. The response will hold a ChallengeString, we need this ChallengeString to get a valid ClientTicket.

C#
if (ServCom.CommandName == "USR")
{
    ChallengeString = ServCom.Param(3);
    break;
}

With the given ChallengeString we will get a valid clientticket.

C#
string clientticket = GetClientTicket(UserPassword, 
                                   UserName, ChallengeString);

This step is a rather large step. I have already wrote an article on this part, read all about it right here.

Finally now we have a ticketID, send it to the server.

C#
WriteCommand("USR", "TWN S " + clientticket, true);
ServCom = ReadCommand();

If we are in luck, we get the USR |transid| OK message. This indicates that we have successfully connected to the MSN servers.

Let's get our username and our screen name, this information was send together with de USR command.

C#
_UserName = ServCom.Param(2);
_ScreenName = ServCom.Param(3);

Last we are going to notify that we are going online, you can put a number of initial status messages here. NLN just means "Online", the rest are:

  • BSY - Busy
  • IDL - Idle
  • BRB - Be Right Back
  • AWY - Away
  • LUN - Out to Lunch
  • PHN - On the Phone
  • FLN - Offline
  • HDN - Hidden
WriteCommand("CHG", "NLN", true);

Now you are connected and everybody who have you in their list will see you online.

Right now, you have to get all the contacts, but that part is too big to explain right here.

Conclusion

Connecting to a MSN server is not that hard, you have to understand what to send and how to reply. Hopefully you have liked this article, so maybe now you want to write your own MSN messenger program.

Good luck!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Traxion
Netherlands Netherlands
I am 27 year and live in the Netherlands. I have graduated in 2004, for the study Computer Science. After my study I have started working as a Technical Consultant in the Identity & Access management branch (http://www.traxion.com).

I have acquired my MCSE and MCSD certifications. Currently I developing a lot of cool things in .NET & Java, I'm also upgrading my certifications to .NET 2.0.

I am the main programmer for the product that we are developing within our company it's called the IM Sequencer (Formally known as the MIIS Sequencer). This product enables users to control the execution from the management agents in MIIS (Microsoft Identity Integration Server) or as it is called now ILM 2007 (Identity Lifecycle Manager 2007) it also generates extensive reports that contains all the results from the management agents that enables administrators to easily track down errors or failures.

Check out the products website http://www.traxionsolutions.com/imsequencer. There are allot of cool features implemented, is uses WMI to connect and communicate with MIIS \ ILM, threading to execute multiple agents, XSLT for reporting transformation, XML for configuration, WinForms for displaying and Win Service for the scheduler engine, very cool!

You can reach me at paul.wijntjes@gmail.com

Comments and Discussions

 
GeneralFantastic - but one small thing Pin
Adam Goossens15-May-04 0:19
Adam Goossens15-May-04 0:19 
GeneralTerrrrrrrrrrrrrrrrrific!!!!!! Pin
JDBP5-Mar-04 6:13
JDBP5-Mar-04 6:13 
GeneralEvents Pin
mikasa25-Dec-03 4:34
mikasa25-Dec-03 4:34 
QuestionLegal? Pin
Gary Brewer11-Nov-03 22:23
Gary Brewer11-Nov-03 22:23 
AnswerRe: Legal? Pin
WillemM12-Nov-03 6:01
WillemM12-Nov-03 6:01 
GeneralRe: Legal? Pin
Gary Brewer12-Nov-03 6:26
Gary Brewer12-Nov-03 6:26 
GeneralRe: Legal? Pin
WillemM12-Nov-03 19:53
WillemM12-Nov-03 19:53 
GeneralRe: Legal? Pin
MBursill13-Nov-03 13:32
MBursill13-Nov-03 13:32 
Trillion gets away with this, there must be a way.

Also, the license agreement for MSN indicates that you can not decompile the SOFTWARE, but it doesn’t mention anywhere anything about the server. In theory what you are releasing is another version of there software, but it's not really using the exact same code they used, it's your variation of it to get it to work with there server. Which, may or may not be protected, I think?!

I'm no lawyer, just guessing.;P

-Mike.
GeneralRe: Legal? Pin
Member 26118818-Nov-03 5:10
Member 26118818-Nov-03 5:10 
GeneralRe: Legal? Pin
SeattleCoder23-Nov-03 13:33
SeattleCoder23-Nov-03 13:33 
GeneralRe: Legal? Pin
Delie8-Apr-04 6:19
Delie8-Apr-04 6:19 
GeneralRe: Legal? Pin
Anonymous2-Jul-04 16:23
Anonymous2-Jul-04 16:23 
GeneralRe: Legal? Pin
Lucktas4-Jul-05 8:53
Lucktas4-Jul-05 8:53 
AnswerRe: Legal? Pin
evildictaitor31-Jul-06 1:42
evildictaitor31-Jul-06 1:42 
GeneralFYI Pin
Zhefu Zhang5-Nov-03 9:11
Zhefu Zhang5-Nov-03 9:11 
GeneralRe: FYI Pin
Paul Wijntjes (dominion99)7-Nov-03 12:15
Paul Wijntjes (dominion99)7-Nov-03 12:15 
GeneralRe: FYI Pin
partyganger7-Nov-03 12:22
partyganger7-Nov-03 12:22 
GeneralIt is really hard to give you that for the HP design ... but, Pin
Zhefu Zhang10-Nov-03 15:03
Zhefu Zhang10-Nov-03 15:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.