Click here to Skip to main content
Click here to Skip to main content

Connecting to MSN messenger with the MSNP9 protocol

, 4 Nov 2003
Rate this:
Please Sign up or sign in to vote.
This article explains how you can connect to MSN using the MSNP9 protocol. It also refers to another article I wrote.


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.

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.

_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.

if( _socket != null )
    _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.

string line;
// check what type of format it should be
if (bSendId) 
    line = string.Format("{0} {1} {2}", command, _transactionID, parameters);
    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.

if (writeNewLine)
// raise the 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.

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

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

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.

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.

string  host = ""; 
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.

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.

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.

  "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.

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.

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.


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.

if (ServCom.CommandName == "USR")
    ChallengeString = ServCom.Param(3);

With the given ChallengeString we will get a valid clientticket.

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.

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.

_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.


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!


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


About the Author

Paul Wijntjes (dominion99)
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 (
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 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

Comments and Discussions

Question这个还能用?是不是MSN 协议已经变了? PinmemberCn2372329-Apr-10 17:40 
GeneralUnknown error occured while connecting... PinmemberBaeltazor5-Feb-10 3:14 
GeneralRe: Unknown error occured while connecting... PinmemberPaul Wijntjes (dominion99)9-Feb-10 20:34 
GeneralRe: Unknown error occured while connecting... PinmemberKreion14-Feb-10 2:58 
GeneralRe: Unknown error occured while connecting... PinmemberWallkysek1-May-12 10:06 
Generalcomplete project PinmemberWrangly15-Oct-08 23:56 
GeneralRetrieve Contact List PinmemberSebouh18113-Sep-07 0:15 
GeneralRe: Retrieve Contact List PinmemberPaul Wijntjes (dominion99)1-Oct-07 1:02 
QuestionRe: Retrieve Contact List PinmemberGazeebo25-Mar-09 14:53 
QuestionStatus not seen by others? PinmemberSebouh18112-Sep-07 23:06 
AnswerRe: Status not seen by others? PinmemberPaul Wijntjes (dominion99)1-Oct-07 0:59 
GeneralNice work PinmemberRunnerDude6-Jul-07 9:27 
GeneralContact list PinmemberErickJackob18-Apr-07 21:40 
GeneralCreate you own Messenger in .NET Pinmembersuhail kaleem22-Oct-06 16:16 
Generaldoes any body knows... Pinmemberb_panic28-Feb-06 14:41 
GeneralChange in code PinmemberPaul Wijntjes (dominion99)24-Jan-06 2:13 
JokeRe: Change in code PinmemberFyska8731-Dec-06 12:22 
GeneralRe: Change in code Pinmemberscript_man14-May-07 3:47 
GeneralVOIP recorder Pinmembertriplebit4-Jan-06 9:05 
GeneralRecording Transmited Voice Pinmembertriplebit4-Jan-06 8:51 
GeneralNice but... PinmemberSuper Lloyd6-Dec-05 2:45 
GeneralRe: Nice but... PinmemberPaul Wijntjes (dominion99)6-Dec-05 22:58 
GeneralRe: Nice but... PinmemberSuper Lloyd7-Dec-05 11:41 
General.NET Messenger library PinsussBas G3-May-05 6:55 
GeneralRe: .NET Messenger library PinmemberUnruled Boy4-May-05 0:04 
GeneralRe: .NET Messenger library PinmemberUnruled Boy4-May-05 1:51 
GeneralRe: .NET Messenger library PinmemberSomeOne_SurVive9-Jun-05 4:48 
GeneralRe: .NET Messenger library PinmemberAlper KARS23-Jul-05 1:37 
QuestionRe: .NET Messenger library PinmemberJason Law5-Jul-07 1:45 
GeneralNice Article But PinmemberMohamed_Bakr15-Feb-05 8:28 
GeneralRe: Nice Article But Pinmemberxoxoxoxoxoxox25-Jan-06 19:43 
General401 at RIGHT login+psd combination PinmemberPanr31-Aug-04 2:10 
GeneralRe: 401 at RIGHT login+psd combination PinmemberAdam Goossens22-Dec-04 23:20 
GeneralHeaders (info) and Help pls Pinmemberbreakbeaterror8-Aug-04 3:54 
GeneralRe: Headers (info) and Help pls Pinmemberbreakbeaterror8-Aug-04 4:22 
GeneralRe: Headers (info) and Help pls PinmemberPaul Wijntjes (dominion99)24-Jan-06 2:15 
GeneralCan't Get Authenticate Ticket Pinmembermax455530-Jun-04 18:06 
GeneralRe: Can't Get Authenticate Ticket PinmemberAdam Goossens8-Jul-04 17:32 
GeneralFantastic - but one small thing PinmemberAdam Goossens15-May-04 1:19 
GeneralTerrrrrrrrrrrrrrrrrific!!!!!! PinmemberJDBP5-Mar-04 7:13 
GeneralEvents Pinmembermikasa25-Dec-03 5:34 
QuestionLegal? PinmemberGary Brewer11-Nov-03 23:23 
AnswerRe: Legal? PinmemberWillemM12-Nov-03 7:01 
GeneralRe: Legal? PinmemberGary Brewer12-Nov-03 7:26 
GeneralRe: Legal? PinmemberWillemM12-Nov-03 20:53 
GeneralRe: Legal? PinmemberMBursill13-Nov-03 14:32 
GeneralRe: Legal? PinmemberDaniël Pelsmaeker18-Nov-03 6:10 
GeneralRe: Legal? PinmemberSeattleCoder23-Nov-03 14:33 
GeneralRe: Legal? PinmemberDelie8-Apr-04 7:19 
GeneralRe: Legal? PinsussAnonymous2-Jul-04 17:23 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 5 Nov 2003
Article Copyright 2003 by Paul Wijntjes (dominion99)
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid