Creating a simple “hello world” application

3.3 Creating a simple “hello world” application

This program will send the words “hello world” over a network. It consists of two executables, one a client, the other a server. These two programs could be physically separated by thousands of kilometers, but as long as the IP addresses of both computers are known, the principle still works.

3.3 Creating a simple “hello world” application 57

In this example, the data will be sent using UDP. This means that the words “hello world” will be bundled up with information that will be used by IP routers to ensure that the data can travel anywhere it wishes in the world. UDP data is not bundled with headers that track message integrity or security. Furthermore, the receiving end is not obliged to reply to the sender with acknowledgments as each packet arrives. The elimination of this requirement allows UDP data to travel with much lower latency than TCP. UDP is useful for small payload transfers, where all of the data to be sent can be contained within one network packet. If there is only one packet, the out-of-sequence problems associated with UDP do not apply; therefore, UDP is the underlying protocol behind DNS.

3.3.1 Writing a simple UDP client

To get started, open Visual Studio .NET, click New Project, then click Visual C# projects, and then Windows Application. Set the name to “ UDP Client ” and press OK. You could alternately click Visual Basic .NET projects and follow the code labeled VB.NET in the examples.

Now, design the form as shown in Figure 3.1. Name the button button1 and the textbox tbHost .

Click the button and type in the source code as follows:

C#

private void button1_Click(object sender, System.EventArgs e) {

UdpClient udpClient = new UdpClient(); udpClient.Connect(tbHost.Text, 8080); Byte[] sendBytes = Encoding.ASCII.GetBytes("Hello World?");

udpClient.Send(sendBytes, sendBytes.Length); }

VB.NET

Private sub button1_Click(sender as object, e as _ System.EventArgs) Handles button1.Click

Dim udpClient as new UdpClient() udpClient.Connect(tbHost.Text, 8080) Dim sendBytes as Byte() sendBytes = Encoding.ASCII.GetBytes("Hello World?")

udpClient.Send(sendBytes, sendBytes.Length) End sub

Chapter 3

58 3.3 Creating a simple “hello world” application

Figure 3.1

UDP client application.

From the code, we can see that the first task is creating a UDP Client object. This is a socket that can send UDP packets. A port number is cho- sen arbitrarily. Here, the port number 8080 is used, simply because it is easy to remember and it is not in the first 1024 port numbers, which are reserved for special use by IANA.

The first argument in the Connect method indicates where any data should be sent. Here, I have used tbHost.Text (i.e., whatever is typed into the textbox). If you have access to only one computer, you would type localhost into this window; otherwise, if you are using two computers, type the IP address of the server.

You also need to include some assemblies by adding these lines to just under the lock of the using statements at the top of the code:

C#

using System.Net; using System.Net.Sockets; using System.Text; using System.IO;

VB.NET

imports System.Net imports System.Net.Sockets imports System.Text imports System.IO

Now, press F5 to compile and run the application. You should see your application resembling Figure 3.1.

Table 3.2 shows the significant methods and properties for UdpClient .

3.3.2 Writing a simple UDP server

The purpose of the UDP server is to detect incoming data sent from the UDP client. Any new data will be displayed in a list box.

3.3 Creating a simple “hello world” application 59

Table 3.2 Significant members of the UdpClient class.

Method or Property

Purpose

Constructor Initializes a new instance of the UdpClient class. For client UDP applications, this is used as new UdpClient (string,int) ; for servers use new UdpClient(int) .

Close() Closes the UDP connection. DropMulticastGroup()

Leaves a multicast group.

JoinMulticastGroup() Adds a UdpClient to a multicast group. This may be invoked thus: JoinMulticastGroup(IPAddress) .

Receive() Returns a UDP datagram that was sent by a remote host. This may be invoked thus: Receive(ref IPEndPoint) . Returns Byte[] .

Send() Sends a UDP datagram to a remote host. This may be invoked thus Send(byte[], int) .

Active Gets or sets a value indicating whether a connection to a remote host has been made. Returns Bool

Client Gets or sets the underlying network sockets. Returns Socket .

As before, create a new C# project, but with a new user interface, as shown below. The list box should be named lbConnections .

A key feature of servers is multithreading (i.e., they can handle hundreds of simultaneous requests). In this case, our server must have at least two threads: one handles incoming UDP data, and the main thread of execu- tion may continue to maintain the user interface, so that it does not appear hung. The details of threading are not within the scope of this book.

First, we write the UDP data handling thread:

C#

public void serverThread() {

UdpClient udpClient = new UdpClient(8080); while(true) {

IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, Chapter 3

60 3.3 Creating a simple “hello world” application

0); Byte[] receiveBytes = udpClient.Receive(ref

RemoteIpEndPoint); string returnData = Encoding.ASCII.GetString(receiveBytes); lbConnections.Items.Add(

RemoteIpEndPoint.Address.ToString() + ":" + returnData.ToString()

VB.NET

Public Sub serverThread()

Dim udpClient as new UdpClient(8080) While true

Dim RemoteIpEndPoint as new IPEndPoint(IPAddress.Any, 0) Dim receiveBytes as Byte() receiveBytes = udpClient.Receive(RemoteIpEndPoint) Dim returnData As String = _ Encoding.ASCII.GetString(receiveBytes) lbConnections.Items.Add _ RemoteIpEndPoint.Address.ToString() + ":" + _ returnData.ToString()

Wend End Sub

Again, we use the UdpClient object. Its constructor indicates that it should be bound to port 8080, like in the client. The Receive method is blocking (i.e., the thread does not continue until UDP data is received). In

a real-world application, suitable timeout mechanisms should be in place because UDP does not guarantee packet delivery. Once received, the data is in byte array format, which is then converted to a string and displayed on- screen in the form source address: data .

There is then the matter of actually invoking the serverThread method asynchronously, such that the blocking method, Receive , does not hang

the application. This is solved using threads as follows:

C#

private void Form1_Load(object sender, System.EventArgs e) {

3.3 Creating a simple “hello world” application 61

Thread thdUDPServer = new Thread(new ThreadStart(serverThread));

thdUDPServer.Start(); }

VB.NET

Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load Dim thdUDPServer = new Thread(new ThreadStart(AddressOf _ serverThread)) thdUDPServer.Start() End Sub

To finish off, the following assemblies are to be added:

C#

using System.Threading; using System.Net; using System.Net.Sockets; using System.Text;

VB.NET

imports System.Threading imports System.Net imports System.Net.Sockets imports System.Text

Figure 3.2

UDP Server application.

Chapter 3

62 3.4 Using TCP/IP to transfer files

To test this application, execute it from Visual Studio .NET. On the same computer, open the UDP client and execute it. Type localhost into the textbox and press the button on the UDP client. A message “Localhost:Hello World?” should appear, such as shown in Figure 3.2.

If you have a second PC, get its IP address and install the server on this second PC and execute it. Again open the client, but type the IP address into the textbox. When you press the button on the client, the server should display the “Hello World” message. Voilà! You have used .NET to send data across a network.