Home > Programming > Network programming in C#

Network programming in C#

Basic definitions

It is important to have a firm understanding about networking. Here, I only mention about some very basic knowledge.

- Protocol: is a set of rules and procedures used for communication. Computers on a network must agree upon a common protocol in order to communicate.

- IP (Internet Protocol) is the method or protocol by which data is sent from one device to another on the Internet. Each computer on the Internet has at least one IP address that uniquely identifies it from all other computers on the Internet. IP by itself is something like the postal system. It allows you to address a package and drop it in the system, but there is no direct link between you and the recipient. Though there are other network protocols available to the Windows network programmer, IP provides the most robust technique for sending data between network devices, especially if they are located across the Internet.

- TCP (Transmission Control Protocol) is one of the main protocols in TCP/IP networks. Whereas the IP protocol deals only with packets, TCP enables two hosts to establish a connection and exchange streams of data. TCP guarantees delivery of data and guarantees that packets will be delivered in the same order in which they were sent. It is connection-oriented protocol (means that a connection must be established before data can be exchanged). Although it was designed to be an Internet protocol, it can also be used as a communication protocol in a private network.

- UDP (User Datagram Protocol) is a connectionless protocol that, like TCP, runs on top of IP networks. Unlike TCP/IP, UDP/IP provides very few error recovery services, offering instead a direct way to send and receive datagram over an IP network. It is used primarily for broadcasting messages over a network.

Beginning network programming

As mentioned earlier, I will develop C# application to interface to the SRV-1 using TCP protocol. The first important thing is to understand how the TCP/IP protocol works. So we are going to involve in a lot of debugging and monitoring network data.

Fortunately, there are some free software available good enough for our purpose. Here I’m using WinPcap and Analyzer. The following portion is only for one new to network programmingJ . I do not expect the expert one to read this.

Microsoft implemented a .NET Socket class, which is a wrapper around the WinSock socket functions. Here is relationship of Socket classes:

C#_Network_Programming

For this project I’ve chose to implement Socket Class in my program since it gives me all the functionality of 3 above classes (TcpListener Class, TcpClient Class, and UdpClient Class) plus much more.

Example to start capturing and monitoring network traffic:

  • Start Analyzer and choose setting something like below:

C#_Network_Programming_TCP IP

  • Now you are ready to observe what is happening inside the network. For testing, I wrote 2 simple C# programs using TCP protocol: one acts as a server listening on port 7 (it is supposed to return any data sent from clients), another one acts as a client. Below listing are the source codes of the two simple programs (in this report, to make it simple and more precise, I directly copy the code from the book TCP/IP sockets in C#: practical guide for programmers rather than put the messy codes that I’ve been debugging on):

For Server side:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;              // For Console, Int32, ArgumentException, Environment
using System.Net;          // For IPAddress
using System.Net.Sockets;  // For TcpListener, TcpClient
 
class TcpEchoServerSocket {
 
  private const int BUFSIZE = 32; // Size of receive buffer
  private const int BACKLOG = 5;  // Outstanding connection queue max size
 
  static void Main(string[] args) {
 
    if (args.Length > 1) // Test for correct # of args
      throw new ArgumentException("Parameters: [
]");
 
    int servPort = (args.Length == 1) ? Int32.Parse(args[0]): 7;
 
    Socket server = null;
 
    try {
      // Create a socket to accept client connections
      server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                          ProtocolType.Tcp);
 
      server.Bind(new IPEndPoint(IPAddress.Any, servPort));
 
      server.Listen(BACKLOG);
    } catch (SocketException se) {
      Console.WriteLine(se.ErrorCode + ": " + se.Message);
      Environment.Exit(se.ErrorCode);
    }
 
    byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer
    int bytesRcvd;                        // Received byte count
 
    for (;;) { // Run forever, accepting and servicing connections
 
      Socket client = null;
 
      try {
        client = server.Accept(); // Get client connection
 
        Console.Write("Handling client at " + client.RemoteEndPoint + " - ");
 
        // Receive until client closes connection, indicated by 0 return value
        int totalBytesEchoed = 0;
        while ((bytesRcvd = client.Receive(rcvBuffer, 0, rcvBuffer.Length,
                                           SocketFlags.None)) > 0) {
          client.Send(rcvBuffer, 0, bytesRcvd, SocketFlags.None);
          totalBytesEchoed += bytesRcvd;
        }
        Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
 
        client.Close();   // Close the socket. We are done with this client!
 
      } catch (Exception e) {
        Console.WriteLine(e.Message);
        client.Close();
      }
    }
  }
}


For Client Side:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System;              // For String, Int32, Console, ArgumentException
using System.Text;         // For Encoding
using System.IO;           // For IOException
using System.Net.Sockets;  // For Socket, SocketException
using System.Net;          // For IPAddress, IPEndPoint
 
class TcpEchoClientSocket
{
 
    static void Main(string[] args)
    {
 
        if ((args.Length < 2) || (args.Length > 3))
        { // Test for correct # of args
            throw new ArgumentException("Parameters:   [
]");
        }
 
        String server = args[0];     // Server name or IP address
 
        // Convert input String to bytes
        byte[] byteBuffer = Encoding.ASCII.GetBytes(args[1]);
 
        // Use port argument if supplied, otherwise default to 7
        int servPort = (args.Length == 3) ? Int32.Parse(args[2]) : 7;
 
        Socket sock = null;
 
        try
        {
            // Create a TCP socket instance
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                              ProtocolType.Tcp);
 
            // Creates server IPEndPoint instance. We assume Resolve returns at least one address
            IPEndPoint serverEndPoint = new IPEndPoint(Dns.Resolve(server).AddressList[0],
                                                       servPort);
 
            // Connect the socket to server on specified port
            sock.Connect(serverEndPoint);
            Console.WriteLine("Connected to server... sending echo string");
 
            // Send the encoded string to the server
            sock.Send(byteBuffer, 0, byteBuffer.Length, SocketFlags.None);
 
            Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
 
            int totalBytesRcvd = 0;   // Total bytes received so far
            int bytesRcvd = 0;        // Bytes received in last read
 
            // Receive the same string back from the server
            while (totalBytesRcvd < byteBuffer.Length)
            {
                if ((bytesRcvd = sock.Receive(byteBuffer, totalBytesRcvd,
                      byteBuffer.Length - totalBytesRcvd, SocketFlags.None)) == 0)
                {
                    Console.WriteLine("Connection closed prematurely.");
                    break;
                }
                totalBytesRcvd += bytesRcvd;
            }
 
            Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd,
                              Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
 
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            sock.Close();
        }
    }
}
  • The client’s IP is 172.17.169.34 and server’s IP is 172.17.168.59
  • The client will send a string “tung” to the server. As soon as the client establish the connection and send that string, you can see something like this in Analyzer:

Network programming Analyzer capturing screen

Overview of Analyzer

Network programming Analyzer capturing screen 2

  • After received string “tung” from the client, the server C# program will return the same string back to the client. Below is what you’ll see in Analyzer:

Network programming Analyzer capturing screen 3

  • Note that in this example the client will open port 3133 to connect to the server.
  • All right, that is quick observing what is happening in the network. Now I am going to show you a bit more details about the packet structures.

I will only show the relevant data (TCP section), the rest of the packet section you can explore on your own to have better understanding.

Packet from the client:

Network programming Analyzer capturing screen 5

Network programming Csharp Analyzer capturing screen 6

The two above figures show the whole packet structure.

Network programming Csharp Analyzer capturing screen 7

The red color section is TCP section (20 bytes)

Network programming Csharp Analyzer capturing screen 8

Client’s port section

Network programming Csharp Analyzer capturing screen 9

Server’s port section

Network programming Csharp Analyzer capturing screen 10

Other data section (here is the string “tung”)

Packet from the server:

Network programming Csharp Analyzer capturing screen 11

The structure of this packet is quite similar to the packet from the client. Note that, in this packet the source port is 7 (because this packet is sent from the server to the client)

Network programming Csharp Analyzer capturing screen 12

The Other data show the byte format data (74756E67) embedded inside the packet (which is “tung” in ASCII)

Below is screen of the server program (which is compiled from the code of section 3.2.1 – server side) and some information of the computer that is running server program.

Network programming Csharp Analyzer capturing screen 13

All right, that was one of the ways in which I started to self-study about Network Programming. I did write and debug those C# programs for my laptop and my PDA (one for server and the other for client). You can do that as well. It is really fun :)

Recommended books for Network Programming

  • C# Network Programming by Richard Blum
  • TCP/IP sockets in C#: practical guide for programmers by David B. Makofske, Michael J. Donahoo, Kenneth L. Calvert.

network_programming_books

SquallLTT

Author: SquallLTT Categories: Programming Tags: , ,
  1. May 29th, 2009 at 12:43 | #1

    Thanks for writing, I really liked reading your most recent post. I think you should post more often, you obviously have natural ability for blogging!

  1. No trackbacks yet.


You can use the following emoticons:

:) ;) :D :)) :P :( B-) :X :-* :blushing: @};- >:D< more »

Easy AdSenser by Unreal