How Many Bytes Can Be Sent Over a Tcp Connection Before Sequence Numbers Start Repeating?

  • Download source files - 345 Kb
  • Download demo - 298 Kb

Image 1

Introduction

The ability of network programming in .NET platform cannot exist denied. Socket programming is the core of network programming in Windows and Linux, and today the .Net platform implements it in a powerful style. In this article, we will see the nuts of socket programming in C#. To exist precise, I have created a control client and a control server, to communicate between a remote server and upward to 200 clients and ship the specified commands to them. Every bit a sample awarding, I have created a chat customer awarding that uses this control client/server to implement chat functions. Before I first explaining my application, allow me give you a small-scale introduction on network programming and sockets taken from the book 'C# network programming', written by Richard Blum.

Sockets

In socket-based network programming, you don't directly access the network interface device to send and receive packets. Instead, an intermediary connector is created to handle the programming interface to the network. Assume that a socket is a connector that connects your application to a network interface of your computer. For sending and receiving data to and from the network you lot should call the socket's methods.

Socket programming in C#

The 'Organisation.Cyberspace.Sockets' namespace contains the classes that provide the actual .NET interface to the depression-level Winsock APIs. In network programming, apart from which programming language to apply in that location are some common concepts like the IP address and port. IP address is a unique identifier of a reckoner on a network and port is similar a gate through which applications communicate with each other. In brief, when we want to communicate with a remote calculator or a device over the network, we should know its IP address. Then, we must open a gate (Port) to that IP then ship and receive the required information.

IP addresses in C#

One of the biggest advantages yous will notice in the .NET network library is the style IP address/port pairs are handled. It is a fairly straightforward procedure that presents a welcome comeback over the old, disruptive UNIX way. .NET defines two classes in the Arrangement.Cyberspace namespace to handle various types of IP address information:

  • IPAddress
  • IPEndPoint

IPAddress

An IPAddress object is used to represent a single IP accost. This value is then used in various socket methods to stand for the IP accost. The default constructor for IPAddress is as follows:

          public          IPAddress(long          address)

The default constructor takes a long value and converts it to an IPAddress value. In exercise, the default is nearly never used. Instead, several methods in the IPAddress class can be used to create and manipulate IP addresses. The Parse() method is often used to create IPAddress instances:

IPAddress newaddress = IPAddress.Parse("          192.168.1.ane");

IPEndPoint

The .NET Framework uses the IPEndPoint object to stand for a specific IP accost/port combination. An IPEndPoint object is used when binding sockets to local addresses, or when connecting sockets to remote addresses.

Connection-oriented and connectionless sockets

The globe of IP connectivity revolves around two types of communication: connexion-oriented and connectionless. In a connexion-oriented socket, the TCP protocol is used to establish a session (connectedness) between two IP address endpoints. There is a fair amount of overhead involved with establishing the connection, but one time information technology is established, the data can be reliably transferred between the devices.

Connectionless sockets utilize the UDP protocol. Because of that no connection information is required to exist sent between the network devices and it is ofttimes difficult to make up one's mind which device is acting equally a "server", and which is acting as a "client". We will focus on the kickoff blazon of socket programming in this article.

Using connection-oriented sockets

In the .Internet Framework, yous can create connectedness-oriented communications with remote hosts across a network. To create a connection-oriented socket, split up sequences of functions must be used for server programs and customer programs:

Image 2

Server

Y'all take four tasks to perform earlier a server can transfer data with a client connectedness:

  1. Create a socket.
  2. Bind the socket to a local IPEndPoint.
  3. Place the socket in listen mode.
  4. Take an incoming connection on the socket.

Creating the server

The commencement step to constructing a TCP server is to create an case of the Socket object. The other iii functions necessary for successful server operations are and then accomplished past using the methods of Socket object. The post-obit C# lawmaking snippet includes these steps:

IPEndPoint localEndPoint =          new          IPEndPoint(IPAddress.Whatsoever,          8000); Socket newsock = Socket(AddressFamily.InterNetwork,                    SocketType.Stream, ProtocolType.Tcp); newsock.Bind(localEndPoint); newsock.Heed(10); Socket client = newsock.Have();

The Socket object created by the Accept() method can now be used to transmit information in either direction betwixt the server and the remote client.

Client

At present that you accept a working TCP server, you tin can create a elementary TCP client programme to interact with it. There are only 2 steps required to connect a client program to a TCP server:

  1. Create a socket.
  2. Connect the socket to the remote server address.

Creating the customer

Equally it was for the server program, the start pace for creating the client program is to create a Socket object. The Socket object is used by the socket Connect() method to connect the socket to a remote host:

IPEndPoint ipep =          new          IPEndPoint(Ipaddress.Parse("          127.0.0.1"),          8000); Socket server =          new          Socket(AddressFamily.InterNetwork,                   SocketType.Stream, ProtocolType.Tcp); server.Connect(ipep);

This example attempts to connect the socket to the server located at address 127.0.0.i.This is the IP address of the local host (current figurer) and is a loopback IP for testing a network application without a network. Of form, you lot can also utilise hostnames along with the Dns.Resolve() method in a real network. (Dns is in System.Net namespace). One time the remote server TCP programme accepts the connectedness asking, the customer programme is fix to transmit data with the server using the standard Send() and Receive() methods.

Blocking problem of network applications

Sockets are in blocking mode by default. In this style they will wait forever to complete their functions, belongings up other functions within the application program until they are complete. Many programs can work quite competently in this mode, merely for applications that work in the Windows programming surround, this can be a problem. There are some means to solve this problem. The first thing that comes to a programmer'due south mind is multi threading. I chose this solution in my application too. This is a simple way when compared to asynchronous network programming or the old 'Not-Blocking sockets' manner.

Our control client/server

After a brief introduction on network programming in C#, I should requite you more details about our command customer/server awarding here. Of course, I can't write a book on network programming in this piffling article. This is only an introduction to network programming. Yous tin find many samples and tutorials on MSDN and CodeProject explaining this concept in detail.

Well-nigh the control server

The server application is a console program. After starting, it volition bind to the '127.0.0.ane' local IP and look on the port 8000 past default for clients. You tin laissez passer the IP and the port of the server as the showtime and 2nd command line parameters when starting the server, if you have a existent network. For example: c:\> ConsoleServer 192.198.0.100 8960.

I used BackgroundWorker to implement multithreading in fourth dimension consuming functions in the server and client. One of these actions includes the acceptance part of the server:

bwListener =          new          BackgroundWorker(); bwListener.DoWork +=          new          DoWorkEventHandler(StartToListen); bwListener.RunWorkerAsync();          individual          void          StartToListen(object          sender , DoWorkEventArgs due east) {          this.listenerSocket =          new          Socket(AddressFamily.InterNetwork,                             SocketType.Stream, ProtocolType.Tcp);          this.listenerSocket.Bind(          new          IPEndPoint(this.serverIP ,          this.serverPort));          this.listenerSocket.Heed(200);          while          (          true          )          this.CreateNewClientManager(this.listenerSocket.Accept()); }

I have a class named ClientManager. When the server is connected to a remote client it passes the advice socket to this class and adds this new ClientManager object to a list of current continued remote clients. Each ClientManager object in the list is responsible for communicating with its remote client. The ClientManager object announces the server with diverse events defined in this class when an action takes identify between the remote customer and the server. These events are:

          public          effect          CommandReceivedEventHandler CommandReceived;

Occurs when a control is received from a remote client.

          public          event          CommandSentEventHandler CommandSent;

Occurs when a control had been sent to the remote client successfully.

          public          event          CommandSendingFailedEventHandler CommandFailed;

Occurs when a command sending action fails. This is may be because of disconnection or sending exception.

          public          result          DisconnectedEventHandler Disconnected;

Occurs when a customer is disconnected from this server.

Sending and receiving data

Since nosotros take a command client/server application we should have a control object to send and receive data. This is implemented in a 'Command' class. This grade is the aforementioned in client and server. When the server wants to ship a command to the client it builds a Command object and and then sends information technology to the client and vice versa.

The command class is good for the user of this code. But in the network, we tin can't ship and receive an object or a type. Everything should exist converted to byte array. And then, we should convert this object to a byte array part past role and send or receive it over the network in real Send and Receive functions within our code. The following code shows the send command method. 'cmd' is the control that we want to send to the remote client:

            byte          [] buffer =          new          byte          [4]; buffer = BitConverter.GetBytes((int)cmd.CommandType);          this.networkStream.Write(buffer ,          0          ,          4);          this.networkStream.Flush();            byte          [] senderIPBuffer =       Encoding.ASCII.GetBytes(cmd.SenderIP.ToString()); buffer =          new          byte          [4]; buffer = BitConverter.GetBytes(senderIPBuffer.Length);          this.networkStream.Write(buffer ,          0          ,          4);          this.networkStream.Affluent();          this.networkStream.Write(senderIPBuffer,          0,                                 senderIPBuffer.Length);          this.networkStream.Flush();                            byte          [] senderNameBuffer =     Encoding.Unicode.GetBytes(cmd.SenderName.ToString()); buffer =          new          byte          [4]; buffer = BitConverter.GetBytes(senderNameBuffer.Length);          this.networkStream.Write(buffer ,          0          ,          4);          this.networkStream.Flush();          this.networkStream.Write(senderNameBuffer,          0,                                 senderNameBuffer.Length);          this.networkStream.Affluent();                            byte          [] ipBuffer =    Encoding.ASCII.GetBytes(cmd.Target.ToString()); buffer =          new          byte          [iv]; buffer = BitConverter.GetBytes(ipBuffer.Length);          this.networkStream.Write(buffer ,          0          ,          4);          this.networkStream.Affluent();          this.networkStream.Write(ipBuffer ,          0          , ipBuffer.Length);          this.networkStream.Flush();            if          ( cmd.MetaData ==          nada          || cmd.MetaData ==          "          "          )     cmd.MetaData =          "          \due north";          byte          [] metaBuffer =            Encoding.Unicode.GetBytes(cmd.MetaData); buffer =          new          byte          [four]; buffer = BitConverter.GetBytes(metaBuffer.Length);          this.networkStream.Write(buffer ,          0          ,          iv);          this.networkStream.Flush();          this.networkStream.Write(metaBuffer,          0, metaBuffer.Length);          this.networkStream.Affluent();

The transport and receive are bidirectional operations. For case, when we ship 4 bytes to the client, the client should read the 4 bytes. We should echo this operation until all the sent information is read. See the receive code of the client here:

          while          (          this.clientSocket.Connected ) {               byte          [] buffer =          new          byte          [4];          int          readBytes =          this.networkStream.Read(buffer ,          0          ,          4);          if          ( readBytes ==          0          )          break;     CommandType cmdType =           (CommandType)( BitConverter.ToInt32(buffer ,          0) );               buffer =          new          byte          [iv];     readBytes =          this.networkStream.Read(buffer ,          0          ,          4);          if          ( readBytes ==          0          )          suspension;          int          senderIPSize = BitConverter.ToInt32(buffer ,          0);               buffer =          new          byte          [senderIPSize];     readBytes =          this.networkStream.Read(buffer ,          0          , senderIPSize);          if          ( readBytes ==          0          )          interruption;     IPAddress senderIP = IPAddress.Parse(              System.Text.Encoding.ASCII.GetString(buffer));               buffer =          new          byte          [iv];     readBytes =          this.networkStream.Read(buffer ,          0          ,          4);          if          ( readBytes ==          0          )          break;          int          senderNameSize = BitConverter.ToInt32(buffer ,          0);               buffer =          new          byte          [senderNameSize];     readBytes =          this.networkStream.Read(buffer,          0, senderNameSize);          if          ( readBytes ==          0          )          break;          string          senderName =          System.Text.Encoding.Unicode.GetString(buffer);                    string          cmdTarget =          "          ";     buffer =          new          byte          [four];     readBytes =          this.networkStream.Read(buffer ,          0          ,          four);          if          ( readBytes ==          0          )          interruption;          int          ipSize = BitConverter.ToInt32(buffer ,          0);               buffer =          new          byte          [ipSize];     readBytes =          this.networkStream.Read(buffer ,          0          , ipSize);          if          ( readBytes ==          0          )          break;     cmdTarget = Organisation.Text.Encoding.ASCII.GetString(buffer);                    string          cmdMetaData =          "          ";     buffer =          new          byte          [four];     readBytes =          this.networkStream.Read(buffer ,          0          ,          4);          if          ( readBytes ==          0          )          break;          int          metaDataSize = BitConverter.ToInt32(buffer ,          0);               buffer =          new          byte          [metaDataSize];     readBytes =          this.networkStream.Read(buffer ,          0          , metaDataSize);          if          ( readBytes ==          0          )          break;     cmdMetaData = Organisation.Text.Encoding.Unicode.GetString(buffer);                        Control cmd =          new          Command(cmdType,                          IPAddress.Parse(cmdTarget), cmdMetaData);     cmd.SenderIP = senderIP;     cmd.SenderName = senderName;          this.OnCommandReceived(new          CommandEventArgs(cmd));     }          this.OnServerDisconnected(new          ServerEventArgs(this.clientSocket));          this.Disconnect(); }

About the control customer

The command customer is very similar to the server. Everything is in the 'CommandClient' class. Since our application is an event driven program this class likewise has some events to announce the user of the occurred actions. Here is a brief definition of these events:

          public          issue          CommandReceivedEventHandler CommandReceived;

Occurs when a command is received from a remote customer.

          public          effect          CommandSentEventHandler CommandSent;

Occurs when a command has been sent to the remote server successfully.

          public          event          CommandSendingFailedEventHandler CommandFailed;

Occurs when a command sending activity fails. This is because of disconnection or sending exception.

          public          event          ServerDisconnectedEventHandler ServerDisconnected;

Occurs when the client is disconnected.

          public          event          DisconnectedEventHandler DisconnectedFromServer;

Occurs when this client is disconnected from the remote server.

          public          outcome          ConnectingSuccessedEventHandler ConnectingSuccessed;

Occurs when this customer is connected to the remote server successfully.

          public          consequence          ConnectingFailedEventHandler ConnectingFailed;

Occurs when this customer fails on connecting to the server.

          public          effect          NetworkDeadEventHandler NetworkDead;

Occurs when the network fails.

          public          event          NetworkAlivedEventHandler NetworkAlived;

Occurs when the network starts to work.

Determination

In this application, you can find the following concepts of .Net programming:

  • Socket programming, server side and client side.
  • Working with resource at runtime.
  • Concurrency management in multi threaded surroundings.
  • Calling windows API functions inside C# code.
  • Creating custom events and eventargs, and throwing events in a UI safe mode.
  • Creating custom exceptions and throwing them every bit and when needed.
  • Generating an HTML folio at runtime dynamically.

And many other .Net programming concepts that I couldn't explain in detail here. The code is fully XML commented and very clear to understand. Please contact me if in that location is any cryptic bespeak or you lot demand any help on my lawmaking.

fochtgromemence1939.blogspot.com

Source: https://www.codeproject.com/Articles/12893/TCP-IP-Chat-Application-Using-C

0 Response to "How Many Bytes Can Be Sent Over a Tcp Connection Before Sequence Numbers Start Repeating?"

Publicar un comentario

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel