Click here to Skip to main content
15,885,366 members
Articles / Programming Languages / C#

STUN Client

Rate me:
Please Sign up or sign in to vote.
4.83/5 (36 votes)
20 Apr 2007CPOL 323.2K   14.9K   85  
STUN client C# implementation with sample application
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace LumiSoft.Net.NNTP.Client
{
    /// <summary>
    /// NNTP client. Definex in RFC 977.
    /// </summary>
    public class NNTP_Client : IDisposable
    {
        private SocketEx m_pSocket   = null;
        private bool     m_Connected = false;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public NNTP_Client()
        {
        }

        #region method Dispose

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        public void Dispose()
        {
            Disconnect();
        }

        #endregion


        #region method Connect

        /// <summary>
        /// Connects to specified NNTP server.
        /// </summary>
        /// <param name="server">NNTP server.</param>
        /// <param name="port">NNTP server port. Defualt NNTP port is 119.</param>
        public void Connect(string server,int port)
        {
            if(m_Connected){
                throw new Exception("NNTP client is already connected, Disconnect first before calling Connect !");
            }

			m_pSocket = new SocketEx();
            m_pSocket.Connect(server,port);
            /*
			if(m_LogCmds && SessionLog != null){
				m_pLogger = new SocketLogger(s,SessionLog);
				m_pLogger.SessionID = Guid.NewGuid().ToString();
				m_pSocket.Logger = m_pLogger;
			}*/

			// Set connected flag
			m_Connected = true;

			// Read server response
			string responseLine = m_pSocket.ReadLine(1000);
            if(!responseLine.StartsWith("200")){
                throw new Exception(responseLine);
            }
        }

        #endregion

        #region method Disconnect

        /// <summary>
        /// Disconnects from NNTP server, trys to send QUIT command before.
        /// </summary>
        public void Disconnect()
        {
            try{
                if(m_Connected){
                    m_pSocket.WriteLine("QUIT");
                    m_pSocket.Shutdown(SocketShutdown.Both);                
                }
            }
            catch{
            }

            m_Connected = false;
            m_pSocket = null;
        }

        #endregion


        #region method GetNewsGroups

        /// <summary>
        /// Gets NNTP newsgoups.
        /// </summary>
        /// <returns></returns>
        public string[] GetNewsGroups()
        {
            /* RFC 977 3.6.1.  LIST

                Returns a list of valid newsgroups and associated information.  Each
                newsgroup is sent as a line of text in the following format:

                    group last first p

                where <group> is the name of the newsgroup, <last> is the number of
                the last known article currently in that newsgroup, <first> is the
                number of the first article currently in the newsgroup, and <p> is
                either 'y' or 'n' indicating whether posting to this newsgroup is
                allowed ('y') or prohibited ('n').

                The <first> and <last> fields will always be numeric.  They may have
                leading zeros.  If the <last> field evaluates to less than the
                <first> field, there are no articles currently on file in the
                newsgroup.
              
                Example:
                   C: LIST
                   S: 215 list of newsgroups follows
                   S: net.wombats 00543 00501 y
                   S: net.unix-wizards 10125 10011 y
                   S: .
            */

            if(!m_Connected){
				throw new Exception("You must connect first");
			}

            // Send LIST command
            m_pSocket.WriteLine("LIST");

            // Read server response
			string responseLine = m_pSocket.ReadLine(1000);
            if(!responseLine.StartsWith("215")){
                throw new Exception(responseLine);
            }

            List<string> newsGroups = new List<string>();
            responseLine = m_pSocket.ReadLine(1000);
            while(responseLine != "."){
                newsGroups.Add(responseLine.Split(' ')[0]);

                responseLine = m_pSocket.ReadLine(1000);
            }

            return newsGroups.ToArray();
        }

        #endregion

        #region method PostMessage

        /// <summary>
        /// Posts specified message to the specified newsgroup.
        /// </summary>
        /// <param name="newsgroup">Newsgroup where to post message.</param>
        /// <param name="message">Message to post. Message is taken from stream current position.</param>
        public void PostMessage(string newsgroup,Stream message)
        {
            /* RFC 977 3.10.1.  POST

                If posting is allowed, response code 340 is returned to indicate that
                the article to be posted should be sent. Response code 440 indicates
                that posting is prohibited for some installation-dependent reason.

                If posting is permitted, the article should be presented in the
                format specified by RFC850, and should include all required header
                lines. After the article's header and body have been completely sent
                by the client to the server, a further response code will be returned
                to indicate success or failure of the posting attempt.

                The text forming the header and body of the message to be posted
                should be sent by the client using the conventions for text received
                from the news server:  A single period (".") on a line indicates the
                end of the text, with lines starting with a period in the original
                text having that period doubled during transmission.

                No attempt shall be made by the server to filter characters, fold or
                limit lines, or otherwise process incoming text.  It is our intent
                that the server just pass the incoming message to be posted to the
                server installation's news posting software, which is separate from
                this specification.  See RFC850 for more details.
              
                Example:
                    C: POST
                    S: 340 Continue posting; Period on a line by itself to end
                    C: (transmits news article in RFC850 format)
                    C: .
                    S: 240 Article posted successfully.
           */

            if(!m_Connected){
				throw new Exception("You must connect first");
			}

            // Send POST command
            m_pSocket.WriteLine("POST");

            // Read server response
			string responseLine = m_pSocket.ReadLine(1000);
            if(!responseLine.StartsWith("340")){
                throw new Exception(responseLine);
            }

            // POST message
            m_pSocket.WritePeriodTerminated(message);

            // Read server response
            responseLine = m_pSocket.ReadLine(1000);
            if(!responseLine.StartsWith("240")){
                throw new Exception(responseLine);
            }

        }

        #endregion


        #region Properties Implementation

        /// <summary>
		/// Gets if NNTP client is connected.
		/// </summary>
		public bool Connected
		{
			get{ return m_Connected; }
		}

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Estonia Estonia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions