A TCP client that uses MSN protocol






3.09/5 (8 votes)
Jul 20, 2004
3 min read

108652

560
A TCP client that uses MSN protocol
Introduction
This is a project that I'd initiated as a messaging platform for communication. MSN protocol is one of the channels chosen, for its "always up and Internet available" feature.
MSN protocol based messaging is just as any other TCP based client program, it means Winsock programming. With asynchronous processing we will make the program response much better. I'm looking more than this, the program should fork its own thread for each individual MSN ID that is online, so that it can broadcast messages using individual channels. Thus it needs multithreaded processing capability.
I've developed this under VB.Net as .Net had provided handy classes that ease these jobs. Comparing the day of only VC having the strong support for these requirements, I'm still remembering the multithreaded socket based server module that I had developed. But then I've encountered a diff problem.
There are 3 major challenges I've encountered during the development
- MSN Protocol communication
- MD5 hashing under VB.Net
- Multithreading an asynchronous processing TCP Client
Using the code
MSN Protocol communication
- There are several sites that maintained information on MSN protocol. MSN Messenger Protocol surely is an interesting site that should not be missed.
- Frankly, I've problems in getting the correct sequence to work under VB.Net, especially on the logon to the server. Until I encountered another project file on CodeProject site that demonstrate the MSN connection – Connecting to MSN
- I've got that to work under VB.Net plus the MSN challenge handling
MD5 Hashing
After the MSN logon, it will receive the challenge key a short while later, we'll need to response back the key, by MD5 hashing the key, plus the original key, in order to keep online. Current version will wait until the challenge acknowledged by the MSN server, then multiple thread will fork for each of the online MSN ID, sending them message.
Function MD5Encrypt(ByVal sInput As String) As String
Dim bytHashValue() As Byte
Dim bytMsgValue() As Byte
Dim Ue As ASCIIEncoding = New ASCIIEncoding
Dim md5 As New MD5CryptoServiceProvider
bytMsgValue = Ue.GetBytes(sInput)
LogToFile("MD5 Key: " + sInput)
bytHashValue = md5.ComputeHash(bytMsgValue)
Dim sOutput As New StringBuilder
Dim iloop As Integer
For iloop = 0 To bytHashValue.Length 8211; 1
sOutput.Append(bytHashValue(iloop).ToString("X2"))
Next
Return sOutput.ToString
End Function
Asynchronous with Multithread
This is the most challenging part. The code work correct as a single thread.
After this point of calling the BeginRead
, any next incoming data received via
TcpClient
will be response to the AsyncCallBack
via
SocketIncomingMsg
. The
EndRead
will captur the incoming data in Byte stream.
readCallBack = New AsyncCallback(AddressOf SocketIncomingMsg)
tcpClient.GetStream.BeginRead(bytDataRead, 0, 1024,
readCallBack, tcpClient.GetStream)
SendMSNCmd("SYN", "1")
Private Sub SocketIncomingMsg(ByVal arMsg As IAsyncResult)
Dim intCount As Integer
intCount = tcpClient.GetStream.EndRead(arMsg)
8230;8230;
End Sub
When I initiated the asynchronous by just triggered the sub routine module (sample: btnTestCon click event). Everything turned out fine.
Start_MSN()
When I've called this via forking another thread to handle, it will fail to read the data from
TCPClient
, the EndRead
will only return an error.
Error such as “Unable to read data from the transport connection.”
The same goes with the section that forked multiple threads, each for one
online MSN ID. They all failed at the same point.
Dim MSNThread As Threading.Thread = New Threading.Thread(AddressOf Start_MSN)
MSNThread.Start()
I've attempt to catch the exception, and following the MSDN documentation, the inner exception too. But the message are not much helpful, (what is error 995 ??)
Catch e As Exception
LogToFile(e.InnerException.ToString())
Exception Output:
'System.Net.Sockets.SocketException:
'The I/O operation has been aborted because of either
'a thread exit or an application request
'at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
'at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
'995
Many other attempts had I tried, but none successes. Finally I focus on
the EndRead
, does this have something to do with asynchronous under multithread
environment? So I called the synchronous processing after the BeginRead
.
readCallBack = New AsyncCallback(AddressOf SocketIncomingMsg)
Dim iarReturn As IAsyncResult = tcpClient.GetStream.BeginRead(bytDataRead, _
0, 1024, readCallBack, tcpClient.GetStream)
iarReturn.AsyncWaitHandle.WaitOne()
It works!!!
Points of Interest
Comparing the previous version of VB, multithread programming under VB.Net is surely more stable, between the debugging and pausing, the development toolkit does not undergo sudden hang, where sometimes a reboot is needed.
But comparing the VC, there is more helpful class now, such as tcpclient, but then this also spelled another layer of re-learning, on top of the standard socket programming. Sometimes I really do not enjoy this. Development is made easy, but the base know-how of the tech is cover up – much like those days I started as VB developer, attempt with VC, the C/C++ old bird always making noise on the delivery, the programs are full of unnecessary lines, and no clean up of objects/class required, a habit that still follows me even now.