Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Create a Chat using Sockets

In this article I will show how we can develop an application which performs communication through Sockets.

Connectivity

Create a Chat using Sockets 

This article discusses:

This article uses the following technologies:

·         What is Sockets;

·         Sockets’ connections;

·         Creation of a Chat.

Visual Studio 2005, Windows Forms and C#.

In this article I will show how we can develop an application which performs communication through Sockets. Using Socket it is possible to develop from application servers, such as a proxy, HTTP servers, FTP, P2P applications, Chat, Download Manager among others. To simplify we will put up a project where the communication between computers will be made.

 

What is Socket?

Socket is a class that interacts with the IP protocol application layer, where it is possible to communicate with applications and network equipment which will be exposed through a communication port. A great example which we can use is the HTTP servers in which the port made available is the “80”. In order to simplify the understanding, I will demonstrate how to develop a Chat through the Socket class.

Let us put up an application that will communicate with other remote instances of the same application, through the port 3030. A central server will not be necessary to coordinate the messages. The main functionality of the application is to function as a Chat, this is, to send and receive messages through a network, be it a local network or Internet.

See in Figure 1 what the functioning of the application will be like. Notice that it works both as server and client, making a peer the peer (P2P) communication possible.

 

Figure 1. Application scheme

 

Creating our application

Open the Visual Studio 2005 and click in File>New>Project; choose the item Windows Application in Visual C#, giving the name of “ChatSocket” to determine the name of the application. In Solution Name type “ChatSocket” and click in OK (Figure 2).

 

Figure 2. Creating a new Windows Application project

 

Initially, the Visual Studio 2005 created some files; we will modify the name of the Form.cs to “frmChat.cs”. Now, we will add some controls before starting the code implementation, as follows in Table 1. The application screen with the controls of Table 1 may be visualized in Figure 3.

 

Control

Name

Text

Label

“lblNick”

“Nickname”

TextBox

“txtNick”

 

Button

“btnAddHost”

“Add Host”

Button

“btnSend”

“Send”

RichTextBox

“rtbChat”

 

RichTextBox

“rtbSend”

 

TextBox

“txtHost”

 

CheckedListBox

“clbUsers”

 

Table 1. Controls to be added in the form

 

Figure 3. Form of the Chat application

 

Now we will initiate the code so that the Chat starts receiving connections from any application through a predefined port. Notice that the architecture used is P2P, where an application receives and sends data without the necessity of a server. In Listing 1 we have the code of the Load event of the form.

 

Listing 1. Initializing the construction of the Chat

using System.Net;

 

public delegate void HandlerGeneric();

 

private void frmChat_Load(object sender, EventArgs e)

{

   this.Text = "Chat - " + Dns.GetHostAddresses(

     Dns.GetHostName())[0].ToString();

   HandlerGeneric init_server = new

     HandlerGeneric(this.StartServer);

   init_server.BeginInvoke(null, init_server);

}

 

In the previous listing, the GetHostName returns the name of the machine where the application was initiated and, with this name it is possible to search the IP address through the GetHostAddresses. Notice that we are using an asynchronous call through the HandlerGeneric delegate, this is necessary so that the application can receive “n” simultaneous connections through StartServer. In Listing 2 we have the implementation of this method.

 

Listing 2. StartServer Method

using System.Net.Sockets;

...

public delegate void HandlerWaitingMessage(Socket s);

...

private void StartServer()

{

   IPAddress ipAddress = Dns.GetHostAddresses(

     Dns.GetHostName())[0];

   TcpListener list = new TcpListener(

     ipAddress, 3030);

   escuta.Start();

 

   HandlerWaitingMessage hndWaitingMessage = new

     HandlerWaitingMessage(this.WaitingMessage);

   while (true)

   {

      Socket s = list.AcceptSocket();

      hndWaitingMessage.BeginInvoke(s, null,

        hndWaitingMessage);

   }

}

 

The StartServer is responsible for the initialization of the server side. Observe that I am using the TcpListener class which is necessary to initiate the listening of port 3030, which occurs when we execute Start.

The delegate HandlerWaitingMessage is used to wait upon any data receiving in asynchronous fashion through the WaitingMessage. Watch that we have an infinite while to wait for some connection to be effected. The AcceptSocket is responsible for the acceptance of the requisition; after the acceptance, the process is paralyzed until a new connection is requested.

At this moment, the AcceptSocket returns an object of the Socket type, which is responsible for keeping the channel with the application which requested a new connection, providing the sending and receiving of data through it. In Listing 3, we have the implementation of the WaitingMessage.

 

Listing 3. WaitingMesssage

private void WaitingMessage(Socket s)

{

   while (s.Connected)

   {

      if (s.Available != 0)

      {

         byte[] buffer = new

           byte[s.ReceiveBufferSize];

         int read = s.Receive(buffer);

         string cmd =

           System.Text.Encoding.ASCII.GetString(

           buffer);

         if (cmd.StartsWith("MSG"))

         {

            string[] msg = cmd.Split(new char[] { ':' });

            recebeuMSG(msg);

         }

      }

      System.Threading.Thread.Sleep(250);

    }

}

 

The WaitingMessage is responsible for the receiving of data. See that the method alone will continue the process if Connected is true, that is, while the client is connected to the application. The Available property indicates if there exists any information to receive after this verification.

Notice that we create one Array of bytes with the size that we will be receiving through the ReceiveBufferSize property. With this, the Receive of the Socket class is responsible for the receiving of the data sent to the application. We will implement the method responsible for the sending of the message, according to Listing 4.

 

Listing 4. Sending data

private void SendMsg()

{

  foreach (object user in clbUser.CheckedItems)

  {

    if (!string.IsNullOrEmpty(user.ToString()))

    {

      if (string.IsNullOrEmpty(rtbSend.Text))

      {

        MessageBox.Show(

          "Message is required.");

        return;

      }

      Socket tempSocket = new Socket(

        AddressFamily.InterNetwork, SocketType.Stream,

        ProtocolType.Tcp);

      try

      {

        tempSocket.Connect(user.ToString(), 3030);

      }

      catch

      {

        clbUser.Items.Remove(user);

        MessageBox.Show(

          "It is not possible to connect");

        return;

      }

      byte[] buffer =

        System.Text.Encoding.ASCII.GetBytes(

        "MSG:" + Dns.GetHostAddresses(

        Dns.GetHostName())[0].ToString()  + ":" +

        txtNick.Text + ":" + rtbSend.Text);

        tempSocket.Send(buffer);

        tempSocket.Close();

      }

      }

      rtbChat.Text += "\r" + string.Format("{0:T}",

        DateTime.Now) + " <<" + txtNick.Text + ">> -" +

        rtbSend.Text;

      rtbSend.Text = "";

}

 

See that I am performing a new connection through the Connect of the Socket class in the 3030 port, informing only the IP and the port. If the users are not available at the moment of the call, it is removed from the list. The second step is to send the data, typed by the user, to the destination selected in the list of users, where we convert the string generated into bytes. This is necessary for us to use Send which is responsible for the sending of the data. Through Listing 5 implement the ReceiverMSG.

 

Listing 5. Receiving Data

private void ReceiverMSG(string[] msg)

{

  if (this.InvokeRequired)

  {

    HandlerReceiverMSG hndmsg = new

      HandlerReceiverMSG(ReceiverMSG);

    this.Invoke(hndmsg, new object[] { msg });

  }

  else

  {

    rtbChat.Text += "\r" + string.Format("{0:T}",

      DateTime.Now) + " <<" + msg[2] + ">> -" +

      msg[3] ;

    if (!clbUser.Items.Contains(msg[1]))

    {

       clbUser.Items.Add(msg[1]);

    }

   }

 }

 

In the ReceiverMSG is where we perform the join of the thread, since as the application functions in an asynchronous manner, it is not possible to manipulate directly the controls of the screen, being necessary to perform the join using the Invoke of the form.

In the Add Host button is where we add the name of the machine where we want to send the messages to, according to Listing 6. For the Send button, in the Click event, add the code of Listing 7.

 

Listing 6. Adding a Host to a list of users

private void btnAddHost_Click(object sender,

  EventArgs e)

{

  try

  {

    if (Dns.GetHostAddresses(

      txtHost.Text).Length != 0)

    {

      if (!string.IsNullOrEmpty(txtHost.Text))

      {

        clbUser.Items.Add(txtHost.Text);

        txtHost.Text = "";

      }

    }

  }

  catch

  {

    txtHost.Text = "";

    txtHost.Focus();

    MessageBox.Show("Invalid Host");

  }

}

 

Listing 7. Send button

private void btnSend_Click(object sender, EventArgs e)

{

  if (!string.IsNullOrEmpty(txtNick.Text))

    SendMsg();

  else

  {

    MessageBox.Show("NickName is required");

    txtNick.Focus();

  }

}

In order to perform a test, it is necessary to execute the application in two different computers, to perform the communication between both of them. In Figure 4, we have application running, being one executed in a server and having access through UltraVNC, but you can use a virtual machine (VMWare or VirtualPC) to test in the same machine.

 

Figure 4. Application running in different machines

 

Conclusion

The article demonstrated how the basic communication is made using Socket, it is possible to use these principles to develop application servers or distributors of any kind of information, for this imagine, ponder and use.

 

Links

Socket (Class) 

msdn2.microsoft.com/pt-br/library/system.net.sockets.socket(VS.80).aspx



colunista nao disponivel

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login