VB.NET IRC Client

EVERYTHING BELOW THIS LINE IS WRONG. Please visit the following updated thread: https://jakash3.wordpress.com/2012/02/13/simple-vb-net-and-csharp-irc-client/


After building my first irc bot, I wish to make a tutorial on making a program to: connect to an irc server, join a channel, and send and receive channel comments. The process involves creating a socket and using it to connect to the server. Once connected, it will send and receive messages from the server which it will parse and output to the screen.

Before we start this tutorial, I assume that you know the common irc commands and you have been in an irc chat before, and also that you VB.NET. We will be making a VB.NET Console Application. In the source code we will first need to define the essential variables that will hold data for bot to use and act upon, including a variable for the socket object:

Dim sock As System.Net.Sockets.Socket
Dim ircserver As String
Dim port As Integer
Dim Channel As String
Dim nick As String

'The following objects are for manipulating the console IN and OUT streams
Dim cout As System.IO.TextWriter = Console.Out
Dim cin As System.IO.TextReader = Console.In

Next, we will prompt the user to enter in information for these variables in order to specify the irc server, port, and channel to connect to as well as their nick name to use.

Sub Main()
cout.WriteLine("My IRC Bot")
cout.Write(vbNewLine)
cout.Write("Server name: ")
ircserver = cin.ReadLine
cout.Write("Port number: ")
port = cin.ReadLine
cout.Write("Channel: ")
channel = cin.ReadLine
cout.Write("Nickname: ")
nick = cin.ReadLine

Now we initialize and connect the socket:

Dim ipHostInfo As System.Net.IPHostEntry = System.Net.Dns.GetHostEntry(ircserver)
Dim EP As New System.Net.IPEndPoint(ipHostInfo.AddressList(0), port)
sock = New System.Net.Sockets.Socket(EP.Address.AddressFamily, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
sock.Connect(ircserver, port)

Once we connect to an irc server with a socket, it is a rule that you send at least the NICK and USER commands to the server. This is where you register and identify yourself as a new user, after that I will give myself a nickname and set my mode status to +B which means Bot:

send("NICK " & nick)
send("USER " & nick & " 0 * :jakash3")
send("JOIN " & channel)
send("MODE " & nick & " +B")

These lines of code will use the send() Sub-procedure to send data to the server. Here’s what that Sub looks like:

Sub send(ByVal msg As String)
msg &= vbCr & vbLf
Dim data() As Byte = System.Text.ASCIIEncoding.UTF8.GetBytes(msg)
sock.send(data, msg.length, socketflags.none)
End Sub

The send sub will first take the argument and append a carriage return and linefeed at the end of the string because irc servers separate each message sent to it by CrLf. Then it will chop that string into a byte array filled with each character of that string and use that as an argument to the send method for the socket to send that data to the server.

Next we will make a loop to have the socket query to receive data from the server for as long as the socket is still connected:

While sock.connected = True
Dim mail As String = recv()
cout.WriteLine(mail)
End While

recv() function will receive a packet of 4096 bytes in length from the server as seen here:

Function recv() As String
Dim data(4096) As Byte
sock.Receive(data, 4096, SocketFlags.None)
Dim mail As String = System.Text.ASCIIEncoding.UTF8.GetString(data)
If mail.Contains(" ") Then
If mail.Substring(0, 4) = "PING" Then
Dim pserv As String = mail.Substring(mail.IndexOf(":"), mail.Length - mail.IndexOf(":"))
pserv = pserv.TrimEnd(Chr(0))
mail = "PING from " & pserv & vbNewLine & "PONG to " & pserv
send("PONG " & pserv)
ElseIf mail.Substring(mail.IndexOf(" ") + 1, 7) = "PRIVMSG" Then
Dim tmparr() As String = Nothing
mail = mail.Remove(0, 1)
tmparr = mail.Split("!")
rnick = tmparr(0)
tmparr = mail.Split(":")
rmsg = tmparr(1)
mail = "msg: " & rnick & ">" & rmsg
End If
End If
mail = mail.TrimEnd(Chr(0))
mail = mail.Remove(mail.LastIndexOf(vbLf), 1)
mail = mail.Remove(mail.LastIndexOf(vbCr), 1)
Return mail
End Function

Now when it receives data from the server the messages we care about the most are the ones that show up on an irc client and the ping requests from the server to check if the client (us) is still active and online. When the server sends a ping request, then we must send a pong message back. When a ping request is sent from a irc server it comes in this format:

PING :sender

Where sender is the name of the server who sent the ping request. If a client gets this message from the server then it must reply back with this message:

PONG :receiver

Where receiver is the name of the server to send the pong reply back to. Well that’s part of what the function does after receiving the packet from the server and converting it to a string. It first analyzes the packet first to see if it’s a ping request and sends a pong reply back to the sender (which is found by extracting the name of the server from the ping message) if it is. Another common type of message that the server sends is the PRIVMSG message. Which means that a user made a comment either to the channel on irc or to you as a private message. The syntax is:

:nick!realname PRIVMSG receiver :msg

Where nick is the nickname of the user sending the message, realname is the realname or addresss of that user, receiver is the name of another user or a channel to send the message to, and msg is the message to send. If the receiver is a channel, then all users will see that message; Otherwise only the user of the username specified on this message will receive that msg. What makes it easier for programs is that the nick and realname are separated by ! and the message is prefixed with :.

Well after all that, if for some reason the While loop breaks and the socket is disconnected, then it will issue the socket.close method and Return from the main sub.
Now since we already know how to send and receive messages to irc servers now you can make you own irc client or bot to process those messages and make replies.
To send a message just use the PRIVMSG command:

PRIVMSG receiver :msg

receiver could be the name of a user or a channel. Remember to prefix the channel with #

For more commands on the irc client protocol read this: http://www.mirc.com/help/rfc2812.txt

18 thoughts on “VB.NET IRC Client

  1. Thanks, this tutorial was a great help because I’m developing my own IRC Client. In a few days, I will release the first beta version at freeirc.windowsbase.de. Maybe you will take a look at this?

  2. @blk: That means that the server your trying to connect to doesn’t exist.

    Also, I’m intergrating this into a form app instead, but when data’s recieved, I try writing it to a textbox and it crashes :/

  3. Are you writing the socket in a different class? If so, you should put this in your Form_Load.

    CheckForIllegalCrossThreadCalls = False

  4. I am having a slight problem, I have copied the code exactly and I am getting the following error appearing on these lines:

    mail = mail.TrimEnd(Chr(0))
    mail = mail.Remove(mail.LastIndexOf(vbLf), 1)
    mail = mail.Remove(mail.LastIndexOf(vbCr), 1)
    Return mail

    Error:

    StartIndex cannot be less than zero.
    Parameter name: startIndex

    The program crashes and it says the above error… anyone have any suggestions?

  5. I have faced problem that IRC send data some times like this
    PRIVMSG 1 :blaalbaaPRIVMSG 2:bloobloo

    this is how they should come from irc:
    PRIVMSG 1 :blaablaa
    PRIVMSG 2:bloobloo
    that means parser goes broke and you can see all prefixes on chat window. i have tried everything i even run socket on different thread to make it handle all data alone. Everything works but this data “overflow” is very confusing.

    What to do?

  6. Pingback: פרויקט שרת-קליינט mIRC (בוט) ב-VB.NET | Yoni Works SN No.1

  7. Pingback: VB.NET Connect to IRC | Tech Arena 24x7

  8. Pingback: Vb.Net 2010 Chat Program

  9. I get error message:

    None of the discovered or specified addresses match the socket address family.
    Parameter name: addresses

    it points at:

    sock.Connect(ircserver, port)

    any suggestions?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: