17 Appendix C Networking

advertisement
1
Appendix C
C
NETWORKING
After studying this appendix
you should have a basic vocabulary about
networking
you should be able to develop a basic
communication system using UDP.
Copyright © 2014 P.J. Blignaut
Appendix C
2
Networking
Networking Basics
Acknowledgement: The text in this section was taken from Wikipedia
Protocols
In telecommunications, a communication protocol is a system of rules that allow two or more entities of
a communications system to transmit information. These rules define the syntax, semantics and
synchronization of communication and possible error recovery methods. Protocols may be implemented by
hardware, software, or a combination of both.
Communication protocols have to be agreed upon by the parties involved. To reach agreement, a protocol
may be developed into a technical standard.
Systems typically do not use a single protocol to handle a transmission. Instead they use a set of
cooperating protocols, sometimes called a protocol family or protocol suite. Some of the best known protocol
suites include: IPX/SPX, X.25, AX.25, AppleTalk and TCP/IP.
To implement a networking protocol, the protocol software modules are interfaced with a framework
implemented on the machine's operating system. This framework implements the networking functionality of
the operating system. The best known frameworks are the TCP/IP model and the OSI model.
The Internet Protocol (IP) is the principal communication protocol in the Internet protocol suite for
relaying datagrams across network boundaries. Its routing function enables internetworking, and essentially
establishes the Internet. IP has the task of delivering packets from the source host to the destination host
solely based on the IP addresses in the packet headers. For this purpose, IP defines packet structures
that encapsulate the data to be delivered. It also defines addressing methods that are used to label the
datagram with source and destination information. The first major version of IP, Internet Protocol Version
4 (IPv4), is the dominant protocol of the Internet. Its successor is Internet Protocol Version 6 (IPv6).
Connectionless communication
In connection-oriented communication the communicating peers must first establish a logical or physical
data channel or connection in a dialog preceding the exchange of user data.
Connectionless
communication, on the other hand, is a data transmission method by which each data unit is individually
addressed and routed based on information carried in each unit, rather than in the setup information of a
prearranged, fixed data channel as in connection-oriented communication. Connectionless communication is
often referred to as CL-mode communication.
Under connectionless communication between two network end points, a message can be sent from one
end point to another without prior arrangement. The device at one end of the communication transmits data
addressed to the other, without first ensuring that the recipient is available and ready to receive the data.
Some protocols allow for error correction by requested retransmission. Internet Protocol (IP) and User
Datagram Protocol (UDP) are connectionless protocols.
The connectionless communications has the advantage over connection-oriented communications in that it
has low overhead. It also allows for multicast (more than one listener specified) and broadcast (unspecified)
operations in which the same data is transmitted to several recipients in a single transmission.
Connectionless protocols are usually described as stateless protocols because the end points have no
protocol-defined way to remember where they are in a "conversation" of message exchanges.
In connectionless transmissions the service provider usually cannot guarantee that there will be no
loss, error insertion, duplication, or out-of-sequence delivery of the packet. However, the effect of errors may
be reduced by implementing error correction within an application protocol.
Error checking
A checksum is a small field from a block of digital data for the purpose of detecting errors which may have
been introduced during its transmission or storage. Checksums are generated through a checksum
function or checksum algorithm on both ends of the transmission. A good checksum algorithm will usually
output a significantly different value, even for small changes made to the input. If the computed checksum on
Copyright © 2014 P.J. Blignaut
Appendix C
3
Networking
the receiving end matches the stored value on the transmission end, there is a very high probability the data
has not been accidentally altered or corrupted.
Check digits and parity bits are special cases of checksums, appropriate for small blocks of data (such
as ID numbers, bank account numbers, computer words, single bytes, etc.).
Handshaking is an automated process of negotiation that dynamically sets parameters of a communications
channel established between two entities before normal communication over the channel begins. It follows
the physical establishment of the channel and precedes normal information transfer.
It is usually a process that takes place when a computer is about to communicate with a foreign device to
establish rules for communication. When a computer communicates with another device like a modem,
printer, or network server, it needs to handshake with it to establish a connection.
A simple handshaking protocol might only involve the receiver sending a message meaning "I received your
last message and I am ready for you to send me another one." A more complex handshaking protocol might
allow the sender to ask the receiver if he is ready to receive or for the receiver to reply with a negative
acknowledgement meaning "I did not receive your last message correctly, please resend it" (e.g. if the data
was corrupted en route).
The TCP/IP three-way handshake
IP Address
An Internet Protocol address (IP address) is a numerical label assigned to each device (e.g., computer,
printer) participating in a computer network that uses the Internet Protocol for communication. An IP address
serves two principal functions: host or network interface identification and location addressing.
The designers of the Internet Protocol defined an IP address as a 32-bit number and this system, known
as Internet Protocol Version 4 (IPv4), is still in use today. However, because of the growth of the Internet and
the predicted depletion of available addresses, a new version of IP (IPv6), using 128 bits for the address,
was developed in 1995. IP addresses are usually written and displayed in human-readable notations, such
as 172.16.254.1 (IPv4), and 2001:db8:0:1234:0:567:8:1 (IPv6).
Ports
A port serves as an endpoint for many types of communication. It is not a hardware device, but a logical
construct that identifies a service or process. A port is always associated with an IP address of a host and
the protocol type of the communication, and thus completes the destination or origination address of a
communications session. A port is identified for each address and protocol by a 16-bit number, commonly
known as the port number. Specific port numbers are often used to identify specific services. Of the
thousands of enumerated ports, 1024 well-known port numbers are reserved by convention to identify
specific service types on a host.
Socket
A network socket is an endpoint of an inter-process communication across a computer network. Today,
most communication between computers is based on the Internet Protocol; therefore most network sockets
are Internet sockets.
Copyright © 2014 P.J. Blignaut
Appendix C
4
Networking
A socket API is an application programming interface (API), usually provided by the operating system, that
allows application programs to control and use network sockets. Internet socket APIs are usually based on
the Berkeley sockets standard.
A socket address is the combination of an IP address and a port number, much like one end of a telephone
connection is the combination of a phone number and a particular extension. Based on this address, internet
sockets deliver incoming data packets to the appropriate application process or thread.
Datagram
A packet transmitted in a connectionless mode is frequently called a datagram. The delivery, arrival time,
and order of arrival need not be guaranteed by the network. It is a “self-contained, independent entity of data
carrying sufficient information to be routed from the source to the destination computer without reliance on
earlier exchanges between this source and destination computer and the transporting network” (RFC 1594).
Each datagram has two components, a header and a data payload. The header contains all the information
sufficient for routing from the originating equipment to the destination without relying on prior exchanges
between the equipment and the network. Headers may include source and destination addresses as well as
a type field. The payload is the data to be transported.
UDP
The User Datagram Protocol (UDP) is one of the core members of the Internet protocol suite. The protocol
was designed by David P. Reed in 1980 and formally defined in RFC 768. UDP uses a simple
connectionless transmission model with a minimum of protocol mechanism. It has no handshaking
dialogues, and thus exposes any unreliability of the underlying network protocol to the user's program. There
is no guarantee of delivery, ordering, or duplicate protection. UDP provides checksums for data integrity,
and port numbers for addressing different functions at the source and destination of the datagram
(Wikipedia).
With UDP, computer applications can send messages in the form of datagrams to other hosts on an Internet
Protocol (IP) network without prior communications to set up special transmission channels or data paths
(i.e. connectionless). UDP is suitable for purposes where error checking and correction is either not
necessary or is performed in the application, avoiding the overhead of such processing at the network
interface level. Time-sensitive applications often use UDP because dropping packets is preferable to waiting
for delayed packets, which may not be an option in a real-time system. If error correction facilities are
needed at the network interface level, an application may use the Transmission Control Protocol (TCP) or
Stream Control Transmission Protocol (SCTP) which are designed for this purpose.
Threading
A thread of execution is the smallest sequence of programmed instructions that can be managed
independently. Multiple threads can exist within the same process, executing concurrently (one starting
before others finish) and share resources such as memory. On a single processor, multithreading is
generally implemented by time slicing (as in multitasking), and the central processing unit (CPU) switches
between different software threads. This generally happens frequently enough that the user perceives the
threads or tasks as running at the same time (in parallel). On a multiprocessor or multi-core system, multiple
threads can be executed in parallel (at the same instant), with every processor or core executing a separate
thread simultaneously.
Make Your Hands Dirty
We will develop a Visual Studio solution with three different executables. Eventually, we will have a
Talker.exe, Listener.exe and DataStructures.dll. The roles of the Talker and Listener are obvious. The
DataStructures.dll will provide us with classes that can be used to encapsulate an object on both the sending
and receiving ends.
Copyright © 2014 P.J. Blignaut
Appendix C
5
Networking
The Talker (Sender of a message)
Start with a new Windows Forms project. Put a rich text box and two buttons on the form as in the screen
print.
 Enter the following code for the Send button:
private void btnSendMessage_Click(object sender, EventArgs e)
{
//Create socket
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
IPAddress sendToIP = IPAddress.Parse("192.168.3.255");
IPEndPoint endPoint = new IPEndPoint(sendToIP, 2000);
//Serialize any object, convert to byte[] and send
MemoryStream strm = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(strm, rtbMessage.Text);
socket.SendTo(strm.ToArray(), endPoint);
socket.Close();
} //btnSendMessage_Click
Things to understand
 The Socket object defines the protocol (UDP) and the type of packet that we will send (datagram).
 We need to specify an IP endpoint (IP address + port) of the destination of the message. Specifying 255
in the last position of the IP means that the message will be broadcasted to all IPs in the range.
 Revisit the basics of serialization in Chapter 13. We now use a MemoryStream instead of a FileStream
and serialize the text message into it.
 Lastly, the serialized message is sent to any listener within the IP rage who is listening at the time.
 Note that the SendTo method always sends data as an array of bytes. Therefore, we need to cast the
data to byte[].
Clear the message on both ends
With some innovation, we can clear the message on both ends. We can, for example, send a special marker
string. When received, the listener will know what to do with it:
 Replace the Serialize method call in the listing above with the following:
formatter.Serialize(strm, “Clear message”);
Copyright © 2014 P.J. Blignaut
Appendix C
6
Networking
The Listener (Receiver of a message)
Start with a new Windows Forms project. Put a label on the form as in the screen print.
 Declare a bool flag, isListening, and a UdpClient object, listener, as data members in the form class:
public partial class CfrmListener : Form
{
private bool isListening = false;
private UdpClient listener;
 Enter the following code for the Shown method handler of the form:
private void CfrmListener_Shown(object sender, EventArgs e)
{
new Thread(ListenForMessage).Start();
} //CfrmListener_Shown
 Add the method to listen for messages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Listen in separate thread
private void ListenForMessage()
{
//Set up listener
int listenPort = 2000;
isListening = true;
listener = new UdpClient(listenPort);
IPEndPoint endPointIP = new IPEndPoint(IPAddress.Any, listenPort);
//Listening loop
while (isListening)
{
try
{
//Blocking call - execution will block here until a message is received
byte[] bytesReceived = listener.Receive(ref endPointIP);
//Check if form exists
if (this.IsHandleCreated)
{
//We need to access the UI from another thread (lblMessage)
this.BeginInvoke((MethodInvoker)delegate()
{
//Put bytes received in memory stream
MemoryStream strm = new MemoryStream();
strm.Write(bytesReceived, 0, bytesReceived.Length);
strm.Seek(0, SeekOrigin.Begin);
//Deserialize the stream
IFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(strm);
strm.Close();
Copyright © 2014 P.J. Blignaut
Appendix C
17
18
19
20
21
22
23
7
Networking
//Handle the message
if (obj.ToString() == "Clear message")
lblMessage.Text = "";
else
lblMessage.Text = obj.ToString();
//Ensure that the UI is updated before the thread is terminated
Application.DoEvents();
}); //Terminate UI thread
} //if
} //try
catch (SocketException ex)
{
MessageBox.Show("Stop listening.");
}
} //while (isListening)
} //Listen
 Stop listening. Add the following code for the form’s FormClosed event handler:
private void CfrmListener_FormClosed(object sender, FormClosedEventArgs e)
{
isListening = false;
listener.Close();
} //CfrmListener_FormClosed
Understand what you are doing
 We start listening for incoming messages as soon as the form is shown on the desktop.
 It is important to understand that the listener.Receive method in line 8 is a blocking method. That
means that execution stops at line 8 until a message is received. This will stop handling of all events in
the same thread. If the blocking method call in line 8 were called from the same thread as that of the user
interface, the program will become unresponsive. Therefore, we had to start a new thread of execution in
the Shown method handler of the form so that the user can still work in the program while waiting for
messages is done on a separate thread in the background.
 Instantiate and prepare the listener object in lines 2 – 4. The port must be the same as in the talker’s
code. We also have to define an IPEndPoint to identify the sender’s IP.
 Line 6 starts a loop that will continue to listen for messages as long as the isListening flag is true.
 The try … catch in lines 7-23 is necessary to handle the change of isListening from true to false in a
graceful way.
 Remember that the waiting loop for messages runs on another thread as that of the user interface. Since
we want to write the message that was received in line 8 to a label on the user interface (so called crossthread operation), we have to temporarily jump out of the current thread to write the message in lines 18
or 20. This can be done by calling the BeginInvoke method of the current user interface object, the form,
in line 10.
 We use a memory stream in lines 11 - 16 to save the byte array of the message that was received in line
8.
 Since we know that the byte array originated from a character string in the Talker program, we can cast
the object returned by the Deserialize method to a string and handle it in lines 17 – 20.
 It is essential that the UI is updated before the temporary execution of the UI thread is terminated in line
21.
 Note the way in which the special marker string to clear the message is handled in lines 17-18.
 The isListening flag is changed to false and the listener closed when the form is closed,
Copyright © 2014 P.J. Blignaut
Appendix C
8
Networking
Communication of objects
Start with a new Class library project. Name it Classes.cs.
 Add the following class to the library. Not that this is a very basic class that is used to illustrate the
priciple and that you will hardly ever encounter such a basic class.
namespace Classes
{
[System.Serializable]
public class CBook
{
public string Author { get; set; }
public string Title { get; set; }
}
}
 Compile the class (press on F6 Build).
 Go back to the Talker and Listener programs and include the Classes.dll as reference in both of
them. (Right-click on References in the Solution explorer, click “Add Reference…”, browse to
Classes.dll and click Add.)
 Also add the using directive to both the Talker and Listener programs.
using Classes;
 Add two text boxes and a Send object button the talker’s form as indicated.
 Enter the following code for the Send object button:
private void btnSendObject_Click(object sender, EventArgs e)
{
//Create object
CBook book = new CBook { Title = txtTitle.Text, Author = txtAuthor.Text };
//Create socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
ProtocolType.Udp);
IPAddress sendToIP = IPAddress.Parse("192.168.3.255");
IPEndPoint endPoint = new IPEndPoint(sendToIP, 2001);
//Serialize object, convert to byte[] and send
MemoryStream strm = new MemoryStream();
new BinaryFormatter().Serialize(strm, book);
socket.SendTo(strm.ToArray(), endPoint);
strm.Close();
socket.Close();
} //btnSendObject_Click
Copyright © 2014 P.J. Blignaut
Appendix C
9
Networking
 Change the ListenForMessage method in the Listener program as follows:
1
2
3
4
5
6
7
8
private void ListenForMessage()
{
//Set up listener
int listenPort = 2000;
isListening = true;
listener = new UdpClient(listenPort);
IPEndPoint endPointIP = new IPEndPoint(IPAddress.Any, listenPort);
//Listening loop
while (isListening)
{
try
{
//Blocking call - execution will block here until a message is received
byte[] bytesReceived = listener.Receive(ref endPointIP);
9
10
11
//Put bytes received in memory stream
MemoryStream strm = new MemoryStream();
strm.Write(bytesReceived, 0, bytesReceived.Length);
strm.Seek(0, SeekOrigin.Begin);
12
13
14
//Deserialize the stream
IFormatter formatter = new BinaryFormatter();
CBook book = (CBook)formatter.Deserialize(strm);
strm.Close();
17
18
19
20
//Handle the message
string s= “Title: “ + book.Title + “\nAuthor: ” + book.Author;
MessageBox.Show(s)
} //try
catch (SocketException ex)
{
MessageBox.Show("Stop listening.");
}
} //while (isListening)
} //Listen
 If all is fine, you should be able to enter data in the fields on the sender’s side, click on the button to
send the object and a message box with the book details should pop up on the receiver’s side.
Understand what you are doing
 Since serialization can be done on any object, we can create a byte array of any object and send it over a
network.
 It is important that the data structure is known to both sender and receiver and therefore we had to create
a separate dll with the data structure and reference it from both the sender and the receiver.
 On the receiver’s side, we can deserialize the object and cast it to the appropriate class.
 Note that, since we don’t access the user interface directly, we don’t have to check for the form’s
existence or jump to the UI thread.
Copyright © 2014 P.J. Blignaut
Appendix C
10
Networking
Keywords
Make sure that you know what each of these items mean or where they are used.
Blocking method
Check digits
Checksums
Connection-oriented
communication
Connectionless communication
Datagram
Deserialize
Error checking
Handshaking
Internet Protocol (IP)
IP Address
Protocol
Serialize
Copyright © 2014 P.J. Blignaut
Socket
Stateless protocols
Parity bit
Port
TCP
TCP/IP
UDP
Download