Request Server responseport port Client

23
Visual C# - Penn P. Wu, PhD. 434 Lecture #14 C# Basic Socket programming Introduction A C# Server Socket Program running on a computer has a socket that bound to a Port Number on the same computer and listening to the client's incoming requests. A C# Client Socket Program has to know the IP Address (Hostname) of the computer that the C# Server Socket Program resides and the Port Number assign for listening for client’s request. Once the connection is established between Server and Client, they can communicate (read or write) through their own sockets. There are two types of communication protocol uses for Socket Programming in C#. They are TCP/IP (Transmission Control Protocol/Internet protocol) Communication and UDP/IP (User Datagram Protocol/Internet protocol) Communication. In order to do communication between two applications in client/server environment, we need some type of addressing, and mechanism or protocol to do proper communication. Communication can be done in two ways: Connection-oriented: In connection oriented service, we establish a proper connection between client and server through some sort of handshaking. For this, we have a protocol or standard called TCP. I.e., TCP provides us service to send data in connection oriented environment. Connectionless: In connection less service, we do data transfer without any connection between client and server. For this, we have a protocol or standard called UDP. I.e., UDP provides us service to send data without taking care of client activation. A Socket is an End-Point of To and From (Bidirectional) communication link between two programs (Server Program and Client Program) running on the same network. You need two programs for communicating a socket application: a Server Socket Program (Server) and a Client Socket Program (Client). C# simplifies the network programming through its namespaces like System.Net and System.Net.Sockets . The System.Net namespace provides a simple programming interface for many of the protocols used on networks today. The System.Net.Sockets namespace provides a managed implementation of the Windows Sockets (Winsock) interface for developers who need to tightly control access to the network. The System.Net.Sockets namespace provides the TcpClient, TcpListener, and UdpClient classes encapsulate the details of creating TCP and UDP connections. It also provides the NetworkStream class with methods for sending and receiving data over Stream sockets in blocking mode. In order to create client and server application, you need to add the following namespaces: using System.Net; using System.Net.Sockets; TCP connection The TcpListener class provides simple methods that listen for and accept incoming connection requests in blocking synchronous mode. Creating a TcpListener object starts with creating an object of the IPAddress class which represents the address of a computer on an IP network. The following initializes a new instance Server port port Client Request response

Transcript of Request Server responseport port Client

Page 1: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 434

Lecture #14 C# Basic Socket programming

Introduction A C# Server Socket Program running on a computer has a socket that bound to a Port Number

on the same computer and listening to the client's incoming requests. A C# Client Socket

Program has to know the IP Address (Hostname) of the computer that the C# Server Socket

Program resides and the Port Number assign for listening for client’s request. Once the

connection is established between Server and Client, they can communicate (read or write) through their own sockets.

There are two types of communication protocol uses for Socket Programming in C#. They are

TCP/IP (Transmission Control Protocol/Internet protocol) Communication and UDP/IP (User

Datagram Protocol/Internet protocol) Communication.

In order to do communication between two applications in client/server environment, we need

some type of addressing, and mechanism or protocol to do proper communication.

Communication can be done in two ways:

• Connection-oriented: In connection oriented service, we establish a proper connection

between client and server through some sort of handshaking. For this, we have a protocol

or standard called TCP. I.e., TCP provides us service to send data in connection oriented environment.

• Connectionless: In connection less service, we do data transfer without any connection

between client and server. For this, we have a protocol or standard called UDP. I.e., UDP

provides us service to send data without taking care of client activation.

A Socket is an End-Point of To and From (Bidirectional) communication link between two

programs (Server Program and Client Program) running on the same network. You need two

programs for communicating a socket application: a Server Socket Program (Server) and a

Client Socket Program (Client).

C# simplifies the network programming through its namespaces like System.Net and

System.Net.Sockets . The System.Net namespace provides a simple programming interface for

many of the protocols used on networks today. The System.Net.Sockets namespace provides a

managed implementation of the Windows Sockets (Winsock) interface for developers who need to tightly control access to the network. The System.Net.Sockets namespace provides the

TcpClient, TcpListener, and UdpClient classes encapsulate the details of creating TCP and

UDP connections. It also provides the NetworkStream class with methods for sending and

receiving data over Stream sockets in blocking mode.

In order to create client and server application, you need to add the following namespaces:

using System.Net;

using System.Net.Sockets;

TCP

connection

The TcpListener class provides simple methods that listen for and accept incoming connection

requests in blocking synchronous mode.

Creating a TcpListener object starts with creating an object of the IPAddress class which

represents the address of a computer on an IP network. The following initializes a new instance

Server port port Client

Request response

Page 2: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 435

of the IPAddress class with the specified address. The Parse() method converts an IP address

string to an IPAddress instance. It can create an instance of IPAddress class from an IP address

expressed in dotted-quad notation for IPv4 and in colon-hexadecimal notation for IPv6.

IPAddress localAddr = IPAddress.Parse("127.0.0.1");

If the IP address will be entered through a textbox (named textBox1), you can use:

IPAddress localAddr = IPAddress.Parse(textBox1.Text);

Where port is a TCP port on which the application will use to listen for incoming connection

attempts. In the .NET Framework, a port is a value of Int32 type. The following specifies a port

number 13000.

Int32 port = 13000;

You need to create an instance of the TcpListener class which listens for connections from

TCP network clients. The following initializes a new instance of the TcpListener class that

listens for incoming connection attempts on the specified local IP address and port number.

TcpListener server = new TcpListener(localAddr, port);

or simply

TcpListener server = new TcpListener(localAddr, 13000);

Notice that the localAddr object must be a IPAddress type. In the following, “204.1.9.114” is

considered a regular string, not a IPAddress value, so the statement simply will not work.

TcpListener server = new TcpListener("204.1.9.114", 13000);

Yet, you can create an instance using the following short-hand way.

TcpListener server = new

TcpListener(IPAddress.Parse("127.0.0.1"), 13000);

If you plan to allow connection across the network. Use the IPAddress.Any field which

indicates that the server must listen for client activity on all network interfaces.

TcpListener server = new TcpListener(IPAddress.Any, 13000);

Use the Start method to begin listening for incoming connection requests. Start will queue

incoming connections until you either call the Stop method. For example,

server.Start();

When the server starts listening, you need to use either a TcpClient or a Socket object to

connect with the TcpListener object. For example, you can declare an object using

TcpClient client;

or

Socket sock = new Socket();

This lecture choose to use TcpClient. To create an instance you can use either AcceptSocket

or AcceptTcpClient to pull a connection from the incoming connection request queue. These

two methods will “block” (means it will perform a blocking call to accept requests). For

Page 3: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 436

example, declare a TcpClient object named “client” and then create an instance using either

AcceptSocket or AcceptTcpClient.

TcpClient client = server.AcceptTcpClient();

or TcpClient client = server.AcceptSocket();

When the clients connect to the server, the transmission between both parties is bilateral (means “two-directions”), as shown below.

The TcpClient type also provides properties to monitor the client’s status. Details are available

at http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient_properties.aspx. For

example,

• Active: Get or set a value that indicates whether a connection has been made.

• Available: Get the amount of data that has been received from the network and is available

to be read.

• Client: Get or sets the underlying Socket.

• Connected: Get a value indicating whether the underlying Socket for a TcpClient is

connected to a remote host.

You can now create a generic socket server as a console or Windows application. A complete

code is available in the learning activity. The following is a functional code, to its minimum,

that can build a TCP server on port 8888. Once a client has connected, it will send the client a

message. In this example, the instructor uses the Connected property to determine if a client has

made the connection.

using System;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

class TCPServer{

public static void Main(){

// setup tcp server

IPAddress localAddr = IPAddress.Parse("127.0.0.1"); //serverIP

TcpListener server = new TcpListener(localAddr, 8888);//port

no.

server.Start(); // start listening

//create an object that represent the client

TcpClient client = server.AcceptTcpClient();

if (client.Connected) {

MessageBox.Show("Server Message: A client connected.");

}

}

}

The above is a simple console code, so it does not need multithreading. When being converted

the GUI-based code needs multithreading support. You need to keep the form and its

components functioning. Meanwhile make sure the application is always listening to the

TcpClient’s call.

Server port port Client

Request response

Page 4: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 437

When the connection is made, it is necessary to have a buffer for reading data from the client.

For example, you can use the Byte structure represents an 8-bit unsigned integer array. The

following is a Byte array with 256 elements.

Byte[] bytes = new Byte[256];

The buffers can hold data, but the code needs a read-and-write function to send and receive

data. The following use the TcpClient.GetStream() method to return a stream. The stream is a

block of data used by both server and client to send and receive data. The NetworkStream

class provides methods for sending and receiving data over the stream sockets in blocking

mode.

NetworkStream stream = client.GetStream();

The NetworkStream class has many methods. For example, you can use the Read and Write methods to read and write data from the network stream between a client and a server. The

syntax of Read method is:

Read(buffer, offset, size)

where buffer is an array of type Byte that is the location in memory to store data read from the

NetworkStream, offset indicates the location in buffer to begin storing the data to, and size is

the number of bytes to read from the NetworkStream. For example,

int i = Read(bytes, 0, bytes.Length);

You can create a loop to receive all the data sent by the client and specify the responses to the

client. A while loop is a good candidate for this task.

NetworkStream stream = client.GetStream();

while((i = stream.Read(bytes, 0, bytes.Length))!=0) {

// Translate data bytes to an ASCII string.

data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

Console.WriteLine("Received: {0}", data);

// Process the data sent by the client using ToUpper

data = data.ToUpper();

byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

// Send back a response.

stream.Write(msg, 0, msg.Length);

Console.WriteLine("Sent: {0}", data);

}

The Encoding.ASCII property gets an encoding for the ASCII (7-bit) character set and 7-bit

ASCII is the default encoding system. Using ASCII encoding has a drawback. ASCII

characters are limited to the lowest 128 Unicode characters. The following example demonstrates how to read a UTF-8 (Unicode) encoded string from a binary file.

public static void Main(){

String str = "This is message with Pi (\u03a0) and Sigma

(\u03a3).";

String utf8Str = "";

Byte[] Bytes = Encoding.UTF8.GetBytes(str);

Page 5: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 438

foreach (Byte b in Bytes) {

utf8Str += b + "\n";

}

MessageBox.Show(str);

MessageBox.Show(utf8Str);

}

If you wish to translate data bytes to UTF-8 strings, use:

data = System.Text.Encoding.UTF8.GetString(bytes, 0, i);

The Encoding.GetString method decodes all the bytes in the specified byte array into a string.

The syntax is:

GetString(bytes, index, count)

where bytes is the byte array containing the sequence of bytes to decode, index is the index of

the first byte to decode, and count is the number of bytes to decode. The following translates data bytes sent by the client to an ASCII string.

data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

The following use the Write methods of the NetworkStream to send the remote client the

response. A sample code in the learning activity will demonstrate how to send response to

clients.

stream.Write(msg, 0, msg.Length);

The .NET Framework provides the Threading class of the System.Threading namespace to

enable C# program to perform concurrent processing. With this support, you can do more than

one operation at a time.

The System.Threading namespace provides classes and interfaces that support multithreaded programming and enable you to easily perform tasks such as creating and starting new threads,

synchronizing multiple threads, suspending threads, and aborting threads.

To incorporate threading in your C# code, add the System.Threading as reference.

using System.Threading;

You can then create a private Thread object, as shown below, and use it to control a the method that listens to the TcpClient’s call. For example,

private Thread thrListener;

....

thrListener = new Thread(serverListening);

thrListener.Start();

To start listening to the TcpClient’s call, simply stop the Thread object. For example,

thrListener.Abort();

The code that illustrates this implementation is available in the learning activity.

Notice that a TextBox control displays its contents from the first to the last line by default.

When a TextBox control has its multiline property set to true, you can use the

Page 6: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 439

TextBox.AppendText() method to append text to the text of the textbox. This method will

insert the text and automatically scroll to the last added line.

If you insist on doing it by hand, you can reposition the caret to the end of the textbox if

necessary (first line) and scroll to the caret (second line)

textBox1.SelectionStart = textBox1.Text.Length;

textBox1.ScrollToCaret();

The client application has similar design concept. The TcpClient class provides client

connections for TCP network services. A client applicant can use it for connecting, sending,

and receiving stream data over a network in synchronous blocking mode.

The following initializes a new instance of the TcpClient class and connects to the specified

port on the specified host.

TcpClient client = new TcpClient("127.0.0.1", 13000);

To allow the users to enter the remote server’s IP address, you can create textbox control and

retrieve the user inputs from the textbox. For example,

TcpClient client = new TcpClient(textBox1.Text, 13000);

The Encoding.ASCII property gets an encoding for the ASCII (7-bit) character set. The

Encoding.GetBytes method encodes a set of characters into a sequence of bytes. The following

can then translate the message into ASCII and store it as a Byte array.

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Hello");

The ASCII encoding is usually appropriate for protocols that require ASCII and is functionally

sufficient for English characters.

To send and receive data, use the GetStream method to obtain a NetworkStream. For example,

NetworkStream stream = client.GetStream();

Use the Write and Read methods of the NetworkStream to send and receive data with the

remote host. The following example sends the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

The following example reads the first batch of the TcpServer response bytes.

Int32 bytes = stream.Read(data, 0, data.Length);

You can call the ASCII.GetString method to translate the binary codes to a string of

characters.

ASCII.GetString(data, 0, bytes);

Unlike the server, the client should send request on demand. Each client request is an individual

event. So, you do not need to create a loop.

You can now create a generic socket TCP client as a console application. A complete code is

available in the learning activity. The following is a functional code, to its minimum, that

creates a client application.

using System;

using System.IO;

Page 7: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 440

using System.Net;

using System.Net.Sockets;

using System.Windows.Forms;

class TCPClient {

public static void Main(){

try {

TcpClient client = new TcpClient("127.0.0.1", 8888);

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Hi");

NetworkStream stream = client.GetStream();

stream.Write(data, 0, data.Length);

MessageBox.Show("The client sent \"Hi\", to server!");

client.Close();

}

catch (Exception e) {

String str = e.Message;

}

}

}

The above code can be converted to a GUI-based Windows application. The complete code is

available in the learning activity. One thing that must be addressed is that a generic C#

Windows Form application has one thread by default. This thread executes the code in the

program starting and ending with the Main method. Every command executed by Main--either directly or indirectly--is performed by the default, or primary thread, and this thread terminates

when Main returns.

When you start the server, and then the client. Both client and server application works 100%

as expected when they are running locally. However, if you try to test them with two

computers, the server and client will not connect. Obviously, the problem was that the above

codes used the IP Address “127.0.0.1” for the TCPListener, as shown below.

IPAddress localAddr = IPAddress.Parse("127.0.0.1");

If you want the server to be accessible remotely, then you need to use the remote IP Address of

the computer (e.g. 192.168.0.119). The following is a class that retrieves the actual IP address

of a server. It is a sample solution.

public static IPAddress GetIPAddress() {

IPHostEntry hostEntry =

Dns.GetHostEntry(Environment.MachineName);

foreach (IPAddress address in hostEntry.AddressList) {

if (address.AddressFamily == AddressFamily.InterNetwork)

return address;

}

return null;

}

To use this class, simply make the following call:

IPAddress ipAddr = GetIPAddress();

TcpListener server = new TcpListener(ipAddr, 8888);

Page 8: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 441

When executing this server application for the first time, you may be asked by the Windows

Firewall to block this program. Be sure to click “Allow access”, so the client application can

access this server application from a remote computer.

Another solution, which is probably better, is to use the IPAddress.Any field which indicates

that the server must listen for client activity on all network interfaces. For example,

TcpListener tcpListener = new TcpListener(IPAddress.Any, 8888);

UDP

connection

UDP is a connectionless transport protocol. You do not need to establish a remote host

connection prior to sending and receiving data. However, you have to make sure the server

exists and will in a later time receive your request.

The UdpClient class provides simple methods for sending and receiving connectionless UDP

datagrams in blocking synchronous mode. You have the option of establishing a default remote

host in one of the following two ways:

• Create an instance of the UdpClient class using the remote host name and port number as

parameters. For example,

UdpClient udpClient = new UdpClient("www.contoso.com",11000);

• Create an instance of the UdpClient class and then call the Connect method. For example,

the UdpClient constructor arbitrarily assigns the local port number.

UdpClient udpClient = new UdpClient(11000);

udpClient.Connect("www.contoso.com", 11000);

The Socket constructor can initialize a new instance of the Socket class using the specified

address family, socket type and protocol. The syntax is:

Socket(addressFamily, socketType, protocolType)

The addressFamily parameter specifies the addressing scheme that the Socket class uses, the

socketType parameter specifies the type of the Socket class, and the protocolType parameter

specifies the protocol used by Socket. The three parameters are not independent. Some address

families restrict which protocols can be used with them, and often the Socket type is implicit in

the protocol.

The following creates a socket object. This is the fundamental device used for network

communications. When creating this object you specify:

• Internetwork: Use the internet communications protocol

• Dgram: Use datagrams or broadcast to everyone rather than send to a specific listener

• Udp: the messages are to be formated as user datagram protocol. Socket sending_socket = new Socket(AddressFamily.InterNetwork,

SocketType.Dgram, ProtocolType.Udp);

Available values of the AddressFamily enumeration can be found at

http://msdn.microsoft.com/en-us/library/system.net.sockets.addressfamily.aspx. Values of

Page 9: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 442

SocketType enumeration is available at http://msdn.microsoft.com/en-

us/library/system.net.sockets.sockettype.aspx. Values of ProtocolType enumeration can be

found at http://msdn.microsoft.com/en-us/library/system.net.sockets.protocoltype.aspx

This UDP server is meant to broadcast to UDP clients. You need to create an IPAddress object and use it to specify the IP address of the client. For example,

IPAddress client = IPAddress.Parse("127.0.0.1");

You can specify a subnet and send UDP messages to all the computers in that subnet. In the

following example, this particular address ends in 255 indicates that UDP message will be sent

to all clients with IP address beginning with 192.168.1.n.

IPAddress client = IPAddress.Parse("192.168.1.255");

Create an object of the IPEndPoint class which represents a network endpoint as an IP address

and a port number. The syntax is:

IPEndPoint(IPAddress, Int32 port)

where IPAddress is a Local IP address and port represents a Int32 type of port number. For

example,

IPEndPoint RemoteIpEndPoint = new IPEndPoint(client, 11000);

You can specify with the Any property for the local IP address and 0 for the local port number

if you want the underlying service provider to assign those values for you. Technically

speaking, the Any field is equivalent to 0.0.0.0 in dotted-quad notation. For example, the

following IPEndPoint object will allow us to read datagrams sent from any source.

IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

If you choose to do this, you can use the LocalEndpoint property to identify the assigned

information, after the socket has connected.

The following is a generic UDP server code.

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

class MyUDPServer {

static void Main(string[] args) {

Socket sendSoc = new Socket(AddressFamily.InterNetwork,

SocketType.Dgram, ProtocolType.Udp);

IPAddress client = IPAddress.Parse("127.0.0.1");

IPEndPoint RemoteIpEndPoint = new IPEndPoint(client, 11000);

Console.WriteLine("Enter text to broadcast via UDP.");

string msg = Console.ReadLine();

byte[] send_buffer = Encoding.ASCII.GetBytes(msg);

Console.WriteLine("sending to address: {0} port: {1}",

RemoteIpEndPoint.Address,

RemoteIpEndPoint.Port);

Page 10: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 443

try {

sendSoc.SendTo(send_buffer, RemoteIpEndPoint);

}

catch (Exception ex) {

string str = ex.Message;

Console.WriteLine("The exception indicates the message was not

sent.");

}

finally{

Console.WriteLine("Message has been sent to the broadcast

address");

}

}

}

You can send to all IP address on your subnet mask. This is known as broadcasting. It is one of the main features of UDP. To send to all clients use IPAddress.Broadcast on the sending and

IPAddress.Any on the receiving. The IPAddress.Broadcast field is equivalent to

255.255.255.255 in dotted-quad notation. The IPAddress.Any field is equivalent to 0.0.0.0 in

dotted-quad notation. For example,

// sending

IPEndPoint groupEP = new IPEndPoint(IPAddress.Broadcast, 11000);

and

// receiving

IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 11000);

To use IPAddress.Broadcast you must set the EnableBroadcast property of the Socket object

(e.g. sendSoc) to true. For example,

sendSoc.EnableBroadcast = true;

The following is a simple but complete code of UDP client application.

using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

public class MyUDPClient {

private const int listenPort = 11000;

public static int Main() {

bool done = false;

UdpClient listener = new UdpClient(listenPort);

IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);

string serverMsg;

byte[] byteArr;

try {

while (!done) {

Console.WriteLine("Waiting for broadcast");

byteArr = listener.Receive(ref groupEP);

Console.WriteLine("Received a broadcast from {0}",

groupEP.ToString() );

Page 11: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 444

serverMsg = Encoding.ASCII.GetString(byteArr, 0,

byteArr.Length);

Console.WriteLine("data follows \n{0}\n\n", serverMsg);

}

}

catch (Exception e) {

Console.WriteLine(e.ToString());

}

listener.Close();

return 0;

}

}

Review

Questions

1. Which can create an instance of IPAddress class? (Assuming the server IP is 204.1.9.114)

A. IPAddress server = "204.1.9.114"; B. IPAddress server = new IPAddress.Parse("204.1.9.114");

C. IPAddress server = IPAddress.Parse("204.1.9.114");

D. IPAddress server = new IPAddress("204.1.9.114");

2. Which initializes a new instance of the TcpListener class that listens for incoming connection

attempts on the specified local IP address 204.1.9.114 and port number 1964?

A. TcpListener server = new TcpListener("204.1.9.114", 1964);

B. TcpListener server = new TcpListener(1964, "204.1.9.114");

C. TcpListener server = new TcpListener((IPAddress) "204.1.9.114", 1964);

D. None of the above

3. Given the following code, which can for the application to begin listening for incoming

connection requests?

TcpListener server = new TcpListener(IPAddress.Any, 13000);

A. server.Connected = true;

B. server.Start();

C. server.Enabled = true;

D. server.Listen();

4. Given the following code, which can determine whether the underlying Socket for a TcpClient is connected to a remote host?

TcpClient client = server.AcceptTcpClient();

A. client.Connected

B. client.Connect()

C. client.Activated

D. client.Socket()

5. Given the following code, which is the correct way to read data from the network stream

between a client and a server?

TcpClient client = server.AcceptTcpClient();

............

Byte[] bytes = new Byte[256];

NetworkStream stream = client.GetStream();

A. Read(bytes, bytes.Length, 0);

B. Read(bytes, 0, bytes.Length);

C. Read(bytes.Length, bytes, 0);

Page 12: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 445

D. Read(0, bytes.Length, bytes);

6. Given the following statement, which is correct?

data = System.Text.Encoding.ASCII.GetString(bytes, 0, 32);

A. bytes is the byte array containing the sequence of bytes to decode

B. 0 is the index of the first byte to decode

C. 32 is the number of bytes to decode

D. All of the above

7. Which can terminate the following threading object?

Thread thread1 = new Thread(serverListening);

A. thread1.Dispose();

B. thread1.Abort(); C. thread1.Stop();

D. thread1.Terminate();

8. If the remote server has an static IP address of 204.10.1.211, which will allow a remote client

to access it?

A. TcpClient client = new TcpClient("127.0.0.1", 8888);

B. TcpClient client = new TcpClient("204.10.1.211", 8888);

C. TcpClient client = new TcpClient(IPAddress.Any, 8888);

D. TcpClient client = new TcpClient(IPAddress.All, 8888);

9. Which can establish a default remote host of the UdpClient class? A. UdpClient udpClient = new UdpClient("www.contoso.com"); Int port= 11000;

B. UdpClient udpClient = new UdpClient(11000); udpClient.Connect("www.contoso.com",

11000);

C. UdpClient udpClient = new UdpClient(11000, "www.contoso.com");

D. UdpClient udpClient = new UdpClient(11000, "www.contoso.com");

udpClient.Connect(11000);

10. The IPAddress.Broadcast field is equivalent to __ in dotted-quad notation

A. 255.255.255.255

B. 255.255.255.0

C. 255.255.0.0

D. 255.0.0.0

Page 13: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 446

Lab #14 Building Server and Client Applications

Learning Activity #1: Building a simple TCP server and client (without data transmission)

1. Create the C:\cis218 directory if it does not exist.

2. Launch the Development Command Prompt.

3. Under the C:\cis218 directory, use Notepad to create a new text file named lab14_1.cs with the following

contents.

using System;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Text;

class MyServer {

public static void Main() {

TcpListener tcpListener = new TcpListener(IPAddress.Any, 8888);

tcpListener.Start();

Socket socket = tcpListener.AcceptSocket();

string responseString = "You have successfully connected to me";

//Forms and sends a response string to the connected client.

Byte[] sendBytes = Encoding.ASCII.GetBytes(responseString);

int i = socket.Send(sendBytes);

if (i != 1) {

MessageBox.Show("Connected", "Server");

}

}

}

4. Type csc.exe /t:winexe lab14_1.cs and press [Enter] to compile.

5. Test the program. Click “Allow Access” when you see the following message (or similar sent by your firewall

application).

6. Use Notepad to create a new text file named “lab14_1_client.cs” with the following contents.

using System;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Windows.Forms;

class TCPClient {

Page 14: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 447

public static void Main(){

try {

TcpClient client = new TcpClient("127.0.0.1", 8888);

Byte[] data = System.Text.Encoding.ASCII.GetBytes("Hi");

NetworkStream stream = client.GetStream();

stream.Write(data, 0, data.Length);

MessageBox.Show("Sent \"Hi\", to server!", "Client");

client.Close();

}

catch (Exception e) {

String str = e.Message;

}

}

}

7. Type csc.exe /t:winexe lab14_1_client.cs and press [Enter] to compile.

8. Launch lab14_1.exe and keep it running, then launch lab14_1_client.exe. A sample output looks:

and

9. Download the “assignment template”, and rename it to lab14.doc if necessary. Capture a screen shot similar to the above and paste it to the Word document named lab14.doc (or .docx).

Learning Activity #2: Building a simple TCP server

1. Under the C:\cis218 directory, use Notepad to create a new text file named lab14_2.cs with the following

contents. using System;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Drawing;

using System.Windows.Forms;

using System.Threading;

public class Form1 : Form {

TextBox textBox1;

Boolean ServRunning = false;

TcpListener server=null;

TcpClient client;

NetworkStream stream;

// The thread that will hold the connection listener

private Thread thrListener;

public Form1() {

Button button1 = new Button();

button1.Text = "Start Server";

Page 15: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 448

button1.Location = new Point(10, 10);

button1.Click += new EventHandler(this.button1_Click);

Controls.Add(button1);

Button button2 = new Button();

button2.Text = "Stop Server";

button2.Location = new Point(190, 10);

button2.Click += new EventHandler(this.button2_Click);

Controls.Add(button2);

textBox1 = new TextBox();

textBox1.Multiline = true;

textBox1.Location = new Point(10, 40);

textBox1.Size = new Size(256, 180);

Controls.Add(textBox1);

}

public void button1_Click(Object sender, EventArgs e) {

// TcpListener server = new TcpListener(port);

server = new TcpListener(IPAddress.Any, 8888);

server.Start(); // start listening for client request

ServRunning = true;

textBox1.Text = "Server started...";

thrListener = new Thread(serverListening);

thrListener.Start();

}

private void serverListening() {

while (ServRunning == true) {

Byte[] bytes = new Byte[256]; // buffer for reading data

try {

// perform a blocking call to accept requests

client = server.AcceptTcpClient();

textBox1.AppendText(Environment.NewLine + "> Client connected!");

String data = null;

// get a stream object for reading and writing

stream = client.GetStream();

int i = stream.Read(bytes, 0, bytes.Length);

// translate data bytes to an ASCII string

data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

textBox1.AppendText(Environment.NewLine + ">> " + data);

// translate a string message to bytes

byte[] msg = System.Text.Encoding.ASCII.GetBytes("Welcome");

stream.Write(msg, 0, msg.Length); // send client the message

// log the message on the textbox

textBox1.AppendText(Environment.NewLine + ">> Server response: \"Welcome\".");

client.Close();

}

catch(Exception ex) {

String str = ex.Message;

}

}

}

Page 16: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 449

public void button2_Click(Object sender, EventArgs e) {

try {

stream.Close();

client.Close();

server.Stop();

thrListener.Abort(); //Stopping thread

ServRunning=false;

}

catch(Exception ex) {

String str = ex.Message;

}

finally {

textBox1.Text = "Server stop...";

}

}

[STAThread]

public static void Main() {

Application.Run(new Form1());

}

}

2. Type csc /t:winexe lab14_2.cs and press [Enter] to compile. Test the program. Click “Allow Access” if

the following (or similar message) appears.

3. Launch lab14_2.exe, click “Start Server”, and keep this program running. You can use the lab14_1_client.exe

file to test this server. A sample output looks:

and

4. Click “Stop Server” to stop the server, and then click “Start Server” to restart it. Test with the client application

again.

5. Capture a screen shot similar to the above and paste it to the Word document named lab14.doc (or .docx).

Learning Activity #3: Building a simple TCP client

1. Under the C:\cis218 directory, use Notepad to create a new text file named lab14_3.cs with the following

contents. using System;

using System.IO;

Page 17: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 450

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Drawing;

using System.Windows.Forms;

public class Form1 : Form {

String message = "Greeting from the client";

TextBox textBox1, textBox2;

TcpClient client;

public Form1() {

this.Width = 335;

Label label1 = new Label();

label1.Text = "Server IP:";

label1.AutoSize = true;

label1.Location = new Point(10, 10);

Controls.Add(label1);

textBox1 = new TextBox();

textBox1.Width = 100;

textBox1.Location = new Point(65, 10);

Controls.Add(textBox1);

textBox2 = new TextBox();

textBox2.Width = 300;

textBox2.Multiline = true;

textBox2.Height = 200;

textBox2.Location = new Point(10, 40);

Controls.Add(textBox2);

Button button1 = new Button();

button1.Text = "Connect";

button1.Width = 60;

button1.Location = new Point(170, 10);

button1.Click += new EventHandler(this.button1_Click);

Controls.Add(button1);

Button button2 = new Button();

button2.Text = "disconnect";

button2.Location = new Point(235, 10);

button2.Click += new EventHandler(this.button2_Click);

Controls.Add(button2);

}

public void button1_Click(Object sender, EventArgs e) {

try {

client = new TcpClient(Convert.ToString(textBox1.Text), 8888);

// Translate the passed message into ASCII and store it as a Byte array.

Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);

// Get a client stream for reading and writing.

NetworkStream stream = client.GetStream();

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

textBox2.AppendText(Environment.NewLine + ">> Sent: " + message);

// Buffer to store the response bytes.

data = new Byte[256];

Page 18: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 451

// String to store the response ASCII representation.

String responseData = String.Empty;

// Read the first batch of the TcpServer response bytes.

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

textBox2.AppendText(Environment.NewLine + ">> Received: " + responseData);

// Close everything.

stream.Close();

}

catch (Exception ex) {

textBox2.AppendText(Environment.NewLine + ex.Message + "....");

}

}

public void button2_Click(Object sender, EventArgs e) {

try {

client.Close();

}

catch (Exception ex) {

String str = ex.Message;

textBox2.AppendText("No connection made yet!");

}

finally {

textBox2.AppendText(Environment.NewLine + "disconnected....");

}

}

[STAThread]

public static void Main() {

Application.Run(new Form1());

}

}

2. Type csc /t:winexe lab14_3.cs and press [Enter] to compile.

3. Launch the lab14_2.exe and keep it running as the server. Test the program by accessing the server. If the server

and client are in the same machine, use 127.0.0.1 as server’s IP address; otherwise, use the correct IP address of

the server. To find the server’s IP address issue “ipconfig” in a Command Prompt of the server. A sample

output looks:

and

4. Capture a screen shot similar to the above and paste it to the Word document named lab14.doc (or .docx).

Learning Activity #4: Building a simple UDP server

1. Under the C:\cis218 directory, use Notepad to create a new text file named lab14_4.cs with the following

contents.

using System;

Page 19: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 452

using System.Drawing;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Text;

public class Form1 : Form {

TextBox textBox1, textBox2;

Label label1;

// IPEndPoint client;

Socket sendSoc;

IPEndPoint groupEP;

public Form1() {

Button button1 = new Button();

button1.Text = "Start Server";

button1.Location = new Point(10, 10);

button1.Click += new EventHandler(this.button1_Click);

Controls.Add(button1);

Button button2 = new Button();

button2.Text = "Send";

button2.Location = new Point(200, 40);

button2.Click += new EventHandler(this.button2_Click);

Controls.Add(button2);

label1 = new Label();

label1.Text = "Enter text to broadcast via UDP:";

label1.AutoSize = true;

label1.Location = new Point(10, 50);

Controls.Add(label1);

textBox1 = new TextBox();

textBox1.Multiline = true;

textBox1.Location = new Point(10, 70);

textBox1.Size = new Size(ClientSize.Width - 20, 50);

textBox1.ScrollBars = ScrollBars.Vertical;

Controls.Add(textBox1);

textBox2 = new TextBox();

textBox2.Multiline = true;

textBox2.Location = new Point(10, 130);

textBox2.Size = new Size(ClientSize.Width - 20, 120);

textBox2.ScrollBars = ScrollBars.Vertical;

Controls.Add(textBox2);

}

public void button1_Click(Object sender, EventArgs e) {

sendSoc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,

ProtocolType.Udp);

// to an individual IP

// IPAddress ipAddr = IPAddress.Parse("192.168.0.119");

// client = new IPEndPoint(ipAddr, 11000);

// send to a subnet

groupEP = new IPEndPoint(IPAddress.Broadcast, 11000);

textBox2.Text = "Server started...";

}

Page 20: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 453

public void button2_Click(Object sender, EventArgs e) {

byte[] send_buffer = Encoding.ASCII.GetBytes(textBox1.Text);

textBox2.AppendText(Environment.NewLine + "> sending to address: " +

IPAddress.Broadcast);

try {

// send to an individual client

//sendSoc.SendTo(send_buffer, client);

// send to a group

sendSoc.EnableBroadcast = true;

sendSoc.SendTo(send_buffer, groupEP);

//sendSoc.Send(send_buffer, send_buffer.Length, groupEP);

}

catch (Exception ex) {

string str = ex.Message;

textBox2.AppendText(Environment.NewLine + ex.Message + " Message not sent.");

}

finally{

textBox2.AppendText(Environment.NewLine + ">> Message has been sent to the

broadcast address.");

}

}

[STAThread]

public static void Main() {

Application.Run(new Form1());

}

}

2. Type csc /t:winexe lab14_4.cs and press [Enter] to compile.

3. Test the program after you complete learning activity #5. A sample output looks:

4. Capture a screen shot similar to the above and paste it to the Word document named lab14.doc (or .docx).

Learning Activity #5: Building a simple UDP client

1. Under the C:\cis218 directory, use Notepad to create a new text file named lab14_5.cs with the following

contents. using System;

using System.Drawing;

using System.Windows.Forms;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

Page 21: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 454

public class Form1 : Form {

TextBox textBox1;

// The thread that will hold the connection listener

private Thread udpListener;

public Form1() {

this.Size = new Size(400, 200);

textBox1 = new TextBox();

textBox1.Text += "> Waiting for broadcast..." + Environment.NewLine;

textBox1.Multiline = true;

textBox1.Location = new Point(10, 10);

textBox1.Size = new Size(ClientSize.Width - 20, ClientSize.Height-20);

textBox1.ScrollBars = ScrollBars.Vertical;

Controls.Add(textBox1);

udpListener = new Thread(serverListening);

udpListener.Start();

}

private void serverListening() {

UdpClient listener = new UdpClient(11000);

IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 11000);

String str = "";

try {

while (true) {

byte[] byteArr = listener.Receive(ref groupEP);

str = ">> Received a broadcast from " + groupEP.ToString() +

Environment.NewLine;

string serverMsg = Encoding.ASCII.GetString(byteArr, 0, byteArr.Length);

str += ">> Message :" + Environment.NewLine + serverMsg;

textBox1.AppendText(str + Environment.NewLine);

}

}

catch (Exception ex) {

str += ex.ToString();

}

finally {

listener.Close();

}

}

[STAThread]

public static void Main() {

Application.Run(new Form1());

}

}

2. Type csc /t:winexe lab14_5.cs and press [Enter] to compile. Click “Allow Access” if being asked by the

firewall application.

3. Launch lab14_5.exe, and click “Start Server”. Test the program. A sample output looks:

Page 22: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 455

and

4. Capture a screen shot similar to the above and paste it to the Word document named lab14.doc (or .docx).

Submittal

1. Complete all the 5 learning activities.

2. Create a .zip file named lab14.zip containing ONLY the following self-executable files.

• lab14_1.exe

• lab14_2.exe

• lab14_3.exe

• lab14_4.exe

• lab14_5.exe

• lab14.doc (or .docx) [You may be given zero point if this Word document is missing]

3. Log in to course site, and enter the course site.

4. Upload the zipped file to question 11 of Assignment.

Programming Exercise:

1. Use Notepad to create a new file named ex14.cs with the following (be sure to replace YourFullNameHere with

the correct one):

//File Name: ex14.cs

//Programmer: YourFullNameHere

using System;

using System.Text;

using System.Net;

using System.Net.Sockets;

public class TCPServer

{

private static int port = 8001;

public static void Main()

{

IPAddress ipAddress = IPAddress.Any;

TcpListener listener = new TcpListener(ipAddress, port);

listener.Start();

Console.WriteLine("Server is running");

Console.WriteLine("Listening on port " + port);

Console.WriteLine("Waiting for connections...");

while (true)

{

Socket s = listener.AcceptSocket();

Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

byte[] b = new byte[65535];

int k = s.Receive(b);

Console.WriteLine("Received:");

Page 23: Request Server responseport port Client

Visual C# - Penn P. Wu, PhD. 456

for (int i = 0; i < k; i++)

Console.Write(Convert.ToChar(b[i]));

ASCIIEncoding enc = new ASCIIEncoding();

s.Send(enc.GetBytes("Server responded"));

Console.WriteLine("\nSent Response");

s.Close();

}

}

}

2. Convert the above console-based TCP server to a GUI-based one.

3. Compile the program. Click “Start Server”. A sample output looks:

4. Download the “programming exercise template”, and rename it to ex14.doc. Capture a screen shot similar to the

above figure and then paste it to the Word document named “ex14.doc” (or .docx).

5. Compress the source code (ex14.cs), the executable (ex14.exe), and the Word document (ex14.doc or .docx) to

a .zip file named “ex14.zip”. You may be given zero point if any of the required file is missing.

Grading Criteria:

• You must be the sole author of the codes.

• You must meet all the requirements in order to earn credits. You will receive zero if you use Visual Studio (C#)

IDE to generate the code.

• No partial credit is given.