Non-blocking Sockets (A Chat Program)
http://www.csharpfriends.com
World's Greatest C# Community    
Home Articles C# Forums Books C# Syntax C# Spec C# Jobs free Source Code Advertise About
 

Control Panel

[ Sign In / register ]
Points   
Notes 
My Forums
My Tutorials
My Profile

Resources

Learn
 Articles
 QuickStarts
 C# Spec
 Whitepapers
 Tools
 Class Browser
 C# Code Generator
 Links
 Misc Rss Feeds
 Code Highlight
 411 Directory
 FREE magazines
 freevb.net

Reviews
  ASP.NET Hosting

Source Code
 Get Version 1.0



C# Consulting
AspDotNetStoreFront
Chapter:   UnCategorized
Current Lesson:
Non-blocking Sockets (A Chat Program)
[Latest Content]
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | ALL
[prev. Lesson]  Regular Expressions [next Lesson]  Display ArrayList content in a DataGrid
Non-blocking Sockets (A Chat Program)
  by: craigrs84

Non-blocking Sockets (A Chat Program)

by: craigrs84

This is a tutorial to explain the use of nonblocking sockets. Non-blocking sockets are the opposite of blocking sockets, and non-blocking sockets do not stop code execution to await incoming data. Non- blocking sockets are more powerful than blocking sockets, but they are also more difficult. I have noticed an advantage to using the Socket class over the TcpListener or TcpClient classes. The TcpListener and TcpClient classes only allow one connection per port number. With the Socket class, you can have as many clients connected to a port as you would like.

This program uses primarily the Socket class. The class TcpSock was built around the Socket class to add ease and functionality.

To start the program you must initialize the Server socket. As you can see, the statement "Server.blocking = false" tells the socket not to block. After initializing the Server socket and binding it to an IP address and port number, the socket is ready to Listen. Now comes the main loop. The first thing we need to check for are incoming connections. Use the Poll method along with the SelectRead argument to do this. When this returns true, we know there is a client trying to connect. So the next thing to do is Accept the connection.

After we have accepted a connection, we can send and receive data. To send the data we simply use the Send method. Receiving data is the hard part. First, we again use the Poll method to check for data available to read. If it returns true, then we call the Recv method, which receives a chunk of data. Telnet does not echo the data unless specifically set to do so, so we will echo the data for telnet. Next we check to see if the person pressed enter... This is this critical part, because we need to know when they have entered a complete line of text, not just a few characters. Once we know they pressed enter, we can send the data to all the other clients using a for loop and the Send method. It's pretty straight- forward.

Lastly, we must close the socket if they disconnect. We already have the information we need. When we Polled the Socket, it returns the number of bytes received. If the number of bytes received = 0, then the Client closed his end of the connection. Now we close our end with the Shutdown and Close methods. Finally, we remove the instance of the TcpSock class from Client, our dynamic array.

This chat program is just a very simple example. If you were ambitious you could add names, commands, and adminstrators.
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TcpSock
{
class TcpSock
{
int    tcpIndx = 0;
int    tcpByte = 0;
byte[] tcpRecv = new byte[1024];

////////////////////////////////////////
public Socket tcpSock;
////////////////////////////////////////

public int Recv  (ref string tcpRead)
{
    tcpByte = tcpSock.Available;
    if (tcpByte > tcpRecv.Length - tcpIndx)
        tcpByte = tcpRecv.Length - tcpIndx;

    tcpByte = tcpSock.Receive(tcpRecv, tcpIndx, tcpByte, 
        SocketFlags.Partial);
    tcpRead = Encoding.ASCII.GetString
        (tcpRecv, tcpIndx, tcpByte);
    tcpIndx+= tcpByte;
    return    tcpRead.Length;
}

public int RecvLn(ref string tcpRead)
{
    tcpRead = Encoding.ASCII.GetString
        (tcpRecv, 0, tcpIndx);
    tcpIndx = 0;
    return    tcpRead.Length;
}

public int Send  (string tcpWrite)
{
    return tcpSock.Send(Encoding.ASCII.GetBytes(tcpWrite));
}

public int SendLn(string tcpWrite)
{
    return tcpSock.Send(Encoding.ASCII.GetBytes(tcpWrite + "\r\n"));
}
}


class Tcp
{
[STAThread]
static void Main()
{
    ////////////////////////////////////////////////////////////////////////////////////////////
    ///class IPHostEntry : Stores information about the Host and is required 
    ///for IPEndPoint.
    ///class IPEndPoint  : Stores information about the Host IP Address and 
    ///the Port number.
    ///class TcpSock     : Invokes the constructor and creates an instance.
    ///class ArrayList   : Stores a dynamic array of Client TcpSock objects.

    IPHostEntry Iphe   = Dns.Resolve   (Dns.GetHostName());
    IPEndPoint  Ipep   = new IPEndPoint(Iphe.AddressList[0], 4444);
    Socket      Server = new Socket    (Ipep.Address.AddressFamily, 
    SocketType.Stream, ProtocolType.Tcp);

    ////////////////////////////////////////////////////////////////////////////////////////////
    ///Initialize
    ///Capacity : Maximux number of clients able to connect.
    ///Blocking : Determines if the Server TcpSock will stop code execution 
    ///to receive data from the Client TcpSock.
    ///Bind     : Binds the Server TcpSock to the Host IP Address and the Port Number.
    ///Listen   : Begin listening to the Port; it is now ready to accept connections.

    ArrayList Client = new ArrayList ();
    string    rln    = null;

    Client.Capacity =   256;
    Server.Blocking = false;
    Server.Bind  (Ipep);
    Server.Listen( 32 );

    Console.WriteLine("{0}: listening to port {1}", Dns.GetHostName(), 
        Ipep.Port);

    ////////////////////////////////////////////////////////////////////////////////////////////
    ///Main loop
    ///1. Poll the Server TcpSock; if true then accept the new connection.
    ///2. Poll the Client TcpSock; if true then receive data from Clients.

    while (true)
    {
        //Accept
        if (Server.Poll(0, SelectMode.SelectRead))
        {
            int i = Client.Add(new TcpSock());
            ((TcpSock)Client[i]).tcpSock = Server.Accept ();
            ((TcpSock)Client[i]).SendLn("Welcome.");
            Console.WriteLine("Client {0} connected.", i  );
        }

        for (int i = 0; i < Client.Count; i++)
        {
            //check for incoming data
            if (((TcpSock)Client[i]).tcpSock.Poll(0, SelectMode.SelectRead))
            {
                //receive incoming data
                if (((TcpSock)Client[i]).Recv(ref rln) > 0)
                {
                    //echo incoming data
                    ((TcpSock)Client[i]).Send(rln);

                    //check for new line
                    if (rln == "\r\n")
                    {
                       ///receive line
                     ((TcpSock)Client[i]).RecvLn(ref rln);

                     //send the line to all clients
                     for (int y = 0; y < Client.Count; y++)
                        if (y != i)
                        ((TcpSock)Client[y]).Send(i.ToString() + ": " + rln);

                         Console.Write("{0}: {1}", i, rln);
                     }
                }
                    //recv returned <= 0; close the socket
                else
                {
                    ((TcpSock)Client[i]).tcpSock.Shutdown(SocketShutdown.Both);
                    ((TcpSock)Client[i]).tcpSock.Close();
                    Client.RemoveAt (i);
                    Console.WriteLine("Client {0} disconnected.", i);
                }
            }
        }
    }
}
}
}




1 


Build Your Own ASP.NET Website Using C# & VB.NET

Chapter:  UnCategorized
Current Lesson:
Non-blocking Sockets (A Chat Program)
[Latest Content]
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | ALL
[prev. Lesson]  Regular Expressions [next Lesson]  Display ArrayList content in a DataGrid



Today's Top Movers
vulpes 6800
MadHatter 2220
jal 867
Jeff1203 857
muster 791

Yesterday Top Movers
shakti sin.. 9
MadHatter 3
Al_Pennywo.. 2
C#fanatic 2
eluvan 1



Monthly Leaders
vulpes 6800
MadHatter 2260
jal 867
Jeff1203 857
muster 791

Top Members
mosessaur 18457
Rincewind 7074
stanleytan 6995
vulpes 6800
Gsuttie 6046

Great Offers
.net hosting
Go To My Pc
Remote Pc Control
zonealarm
spam blocker
web hosting directory
ad server   C#
snadtech GoToMyPc

Top of Page

Advertise | About | Link To Us | Privacy Notice Copyright © 2003 - 2005 CSharpFriends.com  All Rights Reserved  Visual C# Developer Center