How Many Bytes Can Be Sent Over a Tcp Connection Before Sequence Numbers Start Repeating?
- Download source files - 345 Kb
- Download demo - 298 Kb
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:
Server
Y'all take four tasks to perform earlier a server can transfer data with a client connectedness:
- Create a socket.
- Bind the socket to a local
IPEndPoint
. - Place the socket in listen mode.
- 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:
- Create a socket.
- 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