How to NNTP in C#
This is the third in a series of articleson Internet programming with Microsoft's new C# programming language. In thefirst two articles, I wrote two simple TCP/IP classes for SMTP and POP3clients.� In this article, I'm going towrite a simple NNTP class.
NNTP is an older fading protocol in theInternet protocol family. The protocol is used to retrieve news from newsserver, a.k.a. NetNews servers. The protocol works byposting messages into various forums, a.k.a. newsgroups. Then other end-userscan read the recent posts in the forums. There also exist protocols fordistributing NetNews contents amongst various NetNews servers, allowing thousands of servers to sharenews and forums. The most popular news server is of course Microsoft's[nntp://news.microsoft.com]. More often than not, you can launch your NetNews client by typing the nntp URL in your browser'saddress bar.
Listing Error! Bookmark not defined.:Exception Class
public class NntpException: System.ApplicationException
{
������ public NntpException(string str)
������ ������ :base(str)
������ {
������ }
};
I�m still unsure how best to implementexception classes in dot-NET and as such I�ve remained faithful to my C++roots. I�m investigating otherwise and might consider writing a brief articleon just this subject. We�ll see.
Next step is the class declaration. I�mderiving the Nntp class from the TcpClient class inthe System.Net.Sockets namespace of the dot-NETframework.
Listing Error! Bookmark not defined.: NntpClass Declaration
public class Nntp : System.Net.Sockets.TcpClient
We�ll inherit a lot of basicfunctionality from the TcpClient class.
The first method of our Nntp client classis the Connect method. This method takes a server name that represents theremote NNTP server that will service our requests.
Listing Error! Bookmark not defined.: ConnectMethod
public void Connect(string server)
{
������ string response;
������ Connect(server, 119);
������ response = Response();
������ if (response.Substring(0, 3) != "200")
������ {
������ ������ throw new NntpException(response);
������ }
}
We call the Connect method of our base TcpClient class with the server name and port 119. Port 119is the well-known port for NNTP servers. The server should respond with a 200status-code indicating that connection was successful.
When you are finished calling methods tothe Nntp client object, then you should call the Disconnect method to terminatethe connection.
Listing Error! Bookmark not defined.
isconnect Method
public void Disconnect()
{
������ string message;
������ string response;
������ message = "QUIT\r\n";
������ Write(message);
������ response = Response();
������ if (response.Substring(0, 3) != "205")
������ {
������ ������ throw new NntpException(response);
������ }
}
The method will send a QUIT message tothe server and the server should respond with a 205 status-code indicating thatthe it is disconnecting the socket.
When you first instantiate the Nntpobject you should call the Connect method and when you are finished you shouldcall the Disconnect method. In between, you can call three method,GetNewsgroups, GetNews andPost, to receive and send news to the NNTP server.
The GetNewsgroupsmethod, receives from the NNTP server all the forums that are supported by theserver.
Listing Error! Bookmark not defined.: GetNewsgroups Method
public ArrayList GetNewsgroups()
{
������ string message;
������ string response;
������ ArrayList retval = new ArrayList();
������ message = "LIST\r\n";
������ Write(message);
������ response = Response();
������ if (response.Substring(0, 3) != "215")
������ {
������ ������ throw new NntpException(response);
������ }
������ while (true)
������ {
������ ������ response =Response();
������ ������ if (response == ".\r\n" ||
������������� ������ response ==".\n")
������ ������ {
������������� ������ return retval;
������ ������ }
������ ������ else<o:p></o:p>
������ ������ {
������������� ������ char[] seps = { ' ' };
������������� ������ string[] values = response.Split(seps);
������������� ������ retval.Add(values[0]);
������������� ������ continue;
������ ������ }
������ }
}
The GetNewsgroupsmethod begins by sending a LIST message to the NNTP server. The NNTP serverwill respond initially with the 215 status-code indicating that it successfullyreceived the LIST message. Then the NNTP server will respond with a series oflines, each representing one forum on the NNTP server. After all the forums aresent, the NNTP server will send one line with a single period, indicating theend of the forum list. The list of forums is returned from the GetNewsgroups method as an ArrayListof strings.
From the list of forums, you can selectone forum and receive from the GetNews method all thenews for that forum. Call GetNews passing the name ofthe forum to receive the news postings.
Listing Error! Bookmark not defined.: GetNews Method
public ArrayList GetNews(string newsgroup)
{
������ string message;
������ string response;
������ ArrayList retval = new ArrayList();
������ message = "GROUP " + newsgroup + "\r\n";
������ Write(message);
������ response = Response();
������ if (response.Substring(0, 3) != "211")
������ {
������ ������ throw new NntpException(response);
������ }
������ char[] seps= { ' ' };
������ string[] values = response.Split(seps);
������ long start =Int32.Parse(values[2]);
������ long end =Int32.Parse(values[3]);
������ if (start+100 < end&& end > 100)
������ {
������ ������ start = end-100;
������ }
������ for (long i=start;i<end;i++)
������ {
������ ������ message ="ARTICLE " + i + "\r\n";
������ ������ Write(message);
������ ������ response =Response();
������ ������ if (response.Substring( 0, 3) =="423")
������ ������ {
������������� ������ continue;
������ ������ }
������ ������ if (response.Substring( 0, 3) !="220")
������ ������ {
������������� ������ throw new NntpException(response);
������ ������ }
������ ������ string article = "";
������ ������ while (true)
������ ������ {
������������� ������ response =Response();
������������� ������ if (response == ".\r\n")
������������� ������ {
������������� ������ ������ break;
������ ������ ������ }
������������� ������ if (response == ".\n")
������������� ������ {
������������� ������ ������ break;
������������� ������ }
�����������������������
������������� ������ if (article.Length < 1024)
������������� ������ {
������������� ������ ������ article += response;
������������� ������ };
������ ������ }
������ ������ retval.Add(article);
������ }
������ return retval;
}
The GetNewsmethod sends a GROUP message to the NNTP server. The NNTP server will respondswith a status-code of 211, indicating success, the numbers of articles in theforum present the server, the lowest message number for an article in the forumand the highest message number for an article in the forum. The method thenrepeatedly sends an ARTICLE message requesting each article between the lowestand highest message numbers. The NNTP server responds with a 423 status-code ifthe article is not present on the server and a 220 status-code if the articleis present. When we receive a 423 status-code, then we skip to the next messagenumber. When we receive a 220 status-code, the status line is followed by thecontent of the message and terminated with the now familiar with line with onlyone period. As the articles are received then are placed into an ArrayList object and returned from the GetNewsfunction once all messages are received.
Finally, the Post method is used to addnew articles to the forums. The post method takes four parameters; thenewsgroup name, the subject, the sender and the body of the message.
Listing Error! Bookmark not defined.: PostMethod
public void Post(stringnewsgroup, string subject, string from,
string content)
{
������ string message;
������ string response;
������ message = "POST " + newsgroup + "\r\n";
������ Write(message);
������ response = Response(
);
������ if (response.Substring(0, 3) != "340")
������ {
������ ������ throw new NntpException(response);
������ }
������ message = "From: " + from + "\r\n"
������ ������ + "Newsgroups:" + newsgroup + "\r\n"
������ ������ + "Subject: "+ subject + "\r\n\r\n"
������ ������ + content +"\r\n.\r\n";
������ Write(message);
������ response = Response();
������ if (response.Substring(0, 3) != "240")
������ {
������ ������ throw new NntpException(response);
������ }
}
The Post method sends a POST message tothe NNTP server. The POST message takes the newsgroup names as its onlyparameter. The NNTP server should respond with a 340 status-code indicatingthat you may post. The headers and content of the post can then be sent to theserver with a terminating single line containing one period. If the message isreceived correctly, the NNTP server will respond with a 240 status-code.
Our public methods used two privatemethods, Write and Response. The Write method sends a string of bytes to theNNTP server.
Listing Error! Bookmark not defined.: WriteMethod
private void Write(stringmessage)
{
������ System.Text.ASCIIEncoding en = newSystem.Text.ASCIIEncoding() ;
������ byte[] WriteBuffer= new byte[1024];
������ WriteBuffer = en.GetBytes(message);
������ NetworkStream stream = GetStream();
������ stream.Write(WriteBuffer,0,WriteBuffer.Length);
������ Debug.WriteLine("WRITE:" + message);
}
It is important that we convert thedot-NET string to a series of bytes using ASCIIEncodingbefore it is sent to the server. I also call the Debug.WriteLinemethod to send the output string to the debug console to help with debuggingthis component.
The second private method is the Responsemethod. The Response method receives one line of input from the NNTP server.
Listing Error! Bookmark not defined.: ResponseMet
hod
private string Response()
{
������ System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
������ byte []serverbuff = newByte[1024];
������ NetworkStream stream = GetStream();
������ int count = 0;
������ while (true)
������ {
������ ������ byte []buff =new Byte[2];
������ ������ int bytes = stream.Read( buff, 0, 1 );
������ ������ if (bytes == 1)
������ ������ {
������������� ������ serverbuff[count]= buff[0];
������������� ������ count++;
������������� ������ if (buff[0] =='\n')
������������� ������ {
������������� ������ ������ break;
������������� ������ }
������ ������ }
������ ������ else
������ ������ {
������������� ������ break;
������ ������ };
������ };
������ string retval = enc.GetString( serverbuff, 0, count);
������ Debug.WriteLine("READ:" + retval);
������ return retval;
}
After receiving the single line of bytes,the data is translated into a dot-NET string from its ASCII encoded bytes.
Using our NNTP class is quite trivial. Anexample follows.
Listing Error! Bookmark not defined.: Usage
static void Main(string[] args)
{
�����




24. Jan, 2007 by 







No comments yet... Be the first to leave a reply!