Date: 08/03/06 (C Sharp) Keywords: no keywords I'm self-learning C# and last night I felt that I had learned enough to try and make a very simple IRC connection client. And so far it seems to be working fairly well except for the minor fact that you can't really see any of the incoming data. I know this because I've yet to program a way to get it. Why? Because I'm not entirely sure how I should continually get all of the incoming data. This is where I could really use some help. I'd also like some comments or advice on the code itself. It's split up into two files, the Program class which is just the main method, and the IRC class which handles all of the IRC information and commands.
using System;
using System.Collections.Generic;
using System.Text;
namespace IRCtesting
{
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Starting the client..\n");
IRC irc;
if (args.Length == 0)
{
// Create a new IRC connection using the default constructor
irc = new IRC();
}
else
{
// Code to seperate and get the arguments later
irc = new IRC();
}
while (irc.canQuit == false)
{
irc.getCommand();
}
System.Console.WriteLine("Press any key to close the client...\n");
System.Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace IRCtesting
{
class IRC
{
#region variables
// Public variables
public bool canQuit = false;
public bool connected = false;
public static StreamWriter writer;
public static StreamReader reader;
// Private variables
private int ircPort = 6667;
private string ircServer = "irc.magicstar.net";
private string nickNameMain = "CSharpIRC";
private string nickNameBckup = "CSharpIRCbck";
private string user = "USER CSharp 1 * :Dont look at me !!!";
private string channel = "";
private TcpClient ircClient;
private NetworkStream stream;
private Thread pingSender;
// Private constants
private const string CRLF = "\r\n";
private const string PING = "PING :";
#endregion
#region constructors
////////////////////////////////////////////////
//////////////CONSTRUCTORS//////////////////////
// There are six constructors which allow you //
// to specify some or all the information //
// necessary to connecting. //
////////////////////////////////////////////////
public IRC()
{
// Connect to IRC
connect();
}
public IRC(string server)
{
ircServer = server;
// Connect to IRC
connect();
}
public IRC(int port)
{
ircPort = port;
}
public IRC(string server, int port)
{
ircServer = server;
ircPort = port;
// Connect
connect();
}
public IRC(string server, int port, string mainNick)
{
ircServer = server;
ircPort = port;
nickNameMain = mainNick;
}
public IRC(string server, int port, string mainNick, string backupNick)
{
ircServer = server;
ircPort = port;
nickNameMain = mainNick;
nickNameBckup = backupNick;
// Connect to IRC using the settings
connect();
}
#endregion
private void connect()
{
// Tell people we're going to connect
System.Console.WriteLine("Connecting to " + ircServer + ":" + ircPort + " ...\n");
try
{
// Try to make a connection to the server
ircClient = new TcpClient(ircServer, ircPort);
stream = ircClient.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
// Start up our ping handler
PingControl();
// Send the ident information to the server (i.e. our user and who we are)
writer.WriteLine(user);
writer.Flush();
writer.WriteLine("NICK " + nickNameMain);
writer.Flush();
// We're connected, so let's set our bool to true.
connected = true;
}
catch (Exception e)
{
// Show the exception
Console.WriteLine(e.ToString() + CRLF);
// Sleep, before we try again
Thread.Sleep(5000);
connect();
}
}
private void quit()
{
// Message that we're quitting
writer.WriteLine("QUIT ");
writer.Flush();
// Exit out of the program.
quit_program();
}
private void quit(string message)
{
// Message that we're quitting
writer.WriteLine("QUIT " + ":" + message);
writer.Flush();
// Exit out of the program.
quit_program();
}
private void quit_program()
{
// Close everything down
stream.Close();
writer.Close();
reader.Close();
ircClient.Close();
// Tell the console that we can quit and release control
connected = false;
canQuit = true;
}
// Join a channel, no key
private void join(string chan)
{
if (channel == "")
{
channel = chan;
writer.WriteLine("JOIN " + channel);
writer.Flush();
}
else
{
Console.WriteLine("This client only supports one channel right now.\n");
}
}
// Join a channel with a key
private void join(string channel, string key)
{
}
// Send something to the channel
private void sendToChannel(string message)
{
writer.WriteLine("PRIVMSG " + channel + " :" + message);
writer.Flush();
}
////////////////////////////////////////////////
///////////////COMMAND PARSER///////////////////
// The command parser takes the incoming text //
// from the console and splits it up into //
// tokens as well as determines what command //
// has been used and what function should be //
// called. //
////////////////////////////////////////////////
public void getCommand()
{
// Get the command string from the console
string rawCommandString = Console.ReadLine();
// Break the command into their tokenized parts so we can determine what to do
string[] commandString;
commandString = rawCommandString.Split(new char[] { ' ' });
// Get the first element of the command string and convert it to upper case
string command = commandString[0].ToString();
command = command.ToUpper();
///////////////////////////////////////////////////
// The QUIT command. Used to disconnect from the//
// server. It'll also cause our console to stop.//
///////////////////////////////////////////////////
if ((command == "QUIT") || (command == "/QUIT"))
{
// We need to check to see if the person has typed a quit message
int commandLength = commandString.Length;
if (commandLength >= 2)
{
// Determine what the message is.
commandLength = commandString.Length - 1;
string message = "";
for (int i = 1; i <= commandLength; i++)
{
message = message + commandString[i] + " ";
}
// Let's quit with our message
quit(message);
}
else
quit(); // Quit with a default message of your nick.
}
///////////////////////////////////////////////////
// The JOIN command. Used to join an IRC channel//
// and may have a key (if the channel is locked) //
///////////////////////////////////////////////////
if (((command == "JOIN") || (command == "/JOIN") || (command == "/J")))
{
// Set our channel
string chan = commandString[1].ToString();
// Does the channel have the necessary #?
if (!chan.StartsWith("#"))
{
// We'll add it here.
chan = "#" + commandString[1].ToString();
}
// Does this join command have a key for the channel?
// Check for the max number of words in the array first.
int commandLength = commandString.Length;
if (commandLength >= 3)
{
// Is the next word a space or null?
if (commandString[2].ToString() != "")
{
// We have a key! Let's get the key and join the channel.
string key = commandString[2].ToString();
join(chan, key);
}
}
// No, it doesn't, so just join a regular channel
else
join(chan);
}
///////////////////////////////////////////////////
// The "Say" command to send a message to the //
// active channel. //
///////////////////////////////////////////////////
if ((command == "SAY") || (command == "/SAY"))
{
if (channel != "")
{
// Determine what the message is.
int commandLength = commandString.Length -1;
string message = "";
for (int i = 1; i <= commandLength; i++)
{
message = message + commandString[i] + " ";
}
// Send the message to the command
sendToChannel(message);
}
else
{
Console.WriteLine("You must first join a channel.\n");
}
}
}
////////////////////////////////////////////////
////////////////PING CONROL/////////////////////
////////////////////////////////////////////////
// PING control is a set of two functions that//
// will ping the server every 15 seconds on a //
// seperate thread until we are no longer //
// connected to the server. //
////////////////////////////////////////////////
private void PingControl()
{
// Start a new thread for the Ping Control
pingSender = new Thread (new ThreadStart(PingRun));
pingSender.Start();
// Begin running the control
PingRun();
}
// Send PING to irc server every 15 seconds
private void PingRun()
{
// Is the client still running? If so, we need to ping the server
while ((canQuit == false) && (connected == true))
{
writer.WriteLine(PING + ircServer);
writer.Flush();
Thread.Sleep(15000);
}
}
}
}
I'm also not entirely sure how to go about splitting up the args[] and determining which constructor to use based on that. However, once I get the incoming information working and displaying correctly I more or less plan to scrap the console version and move onto a more GUI-based client so I'm not too worried about that.
|