TCP Client Server programming using TCP with C# .NET2
[20 mn of reading - published 6/3/2006 6:29:38 PM - Target : Confirmé]
|
   
|
Author
3. Coding the server
3.1. Overview
As we saw in previous chapters, 3 classes have to be created for the server:
- The class that will await connections
- The class that will manage 1 connection (Very similar to the Client Connection class)
- And then, the Windows Form to make the server stop or start...
There will be a Thread per connection, a thread for the server plus the principal thread.
We have already seen the Connection class (client-side: chapter 2.), the method used to send and receive data, and how we could format messages to avoid fragmentation effects.
3.2. Waiting for connections
The class waiting for connection (we call it server class) will create the connection classes and bring them an open tcpClient representing the accepted incoming connection. This class will have to manage open threads and connections that are unused.
///
/// Server class code, wait for connections ///
public class Server
{
//Connections private List connexions;
//Server's thread private Thread thread;
//Property of the server public int Port = 22;//(port 22)
public IPAddress IPAddressToBind;
//The TCP Server private TcpListener tcpListener;
//Method to stop the server public void Stop()
{
try
{
if (tcpListener!=null)
tcpListener.Stop();
if (thread != null)
if (thread.IsAlive)
thread.Join(1000);
}
catch(Exception)
{
}
}
//Constructor public Server()
{
this.IPAddressToBind = new IPAddress(
Encoding.ASCII.GetBytes("127.0.0.1"));
connexions = new List();
thread = new Thread(new ThreadStart(Listen));
thread.Start();
}
//Await connections public void Listen()
{
try
{
tcpListener = new TcpListener(IPAddressToBind, Port);
tcpListener.Start();
Connexion current;
while (true)
{
current = new Connexion(
tcpListener.AcceptTcpClient());//Exception if stop.
connexions.Add(current);
}
}
catch (ThreadAbortException ex)
{
//Throw the event?
}
catch (Exception ex)
{
//Throw the event?
}
}
} |
The Thread we have just created will block at the following line: "current = new Connexion(tcpListener.AcceptTcpClient()); "
As an incoming connection arrives, a Connection class is created and will manage this newly accepted connection. As we said, this class is very similar to the Client's connection class. We will just tranfer it the accepted TcpClient as the connection is already established.
The Stop method has to be called to stop the server thread (waiting for incoming connections).
If you want to listen to the default network interface, you may need the following code to retrieve the primary IP Address of the machine:
public static IPAddress LocalIP()
{
string sz_hostname = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostEntry(sz_hostname);
IPAddress[] addr = ipEntry.AddressList;
if (addr != null)
if (addr.Length > 0)
return addr[0];
return null;
} |
You can implement events to transmit to the server class the connection state when a change occurs.
Don't forget to set your lock statement whenever you manipulate a shared object on more than one thread.
3.3. Maintaining the connection
It can take a lot of time before TCP detects that the connection is broken. Therefore you should send periodic packets in order to know if the connection is still open and remains usable.
You just have to:
- Send a periodic packet
- Catch the exception thrown by the NetworkStream(_send Method)
- Close the connection and the NetworkStream
- Stop the connection thread
- Remove the connection object from the list of connections located inside the server class.
3.4. Communication flow control
The server should control and cut the different messages arriving or being sent before executing any operation.
The principle of message encoding and delimitation are the same as the client. Message encoding using a termination string, or structure serialization should be a good way to face the message fragmentation problems.
|