Outils pour utilisateurs

Outils du site


lang:csharp:net:client_serveur

Table des matières

TCP

TcpClient

Les interfaces

Les fonctionnalités du serveur sont dans une Class Library à part et commune aux projets client / serveur.

IServeurFonctions.cs
namespace Common
{
    public interface IServeurFonctions
    {
        bool ArretPoste();
    }
}

Coté serveur :

IServeur.cs
namespace Serveur
{
    interface IServeur
    {
        bool Connect(ushort port);
        void Join();
        void StopListening();
    }
}
IServeurImpl.cs
namespace Serveur
{
    interface IServeurImpl : IServeur, IServeurFonctions
    {
    }
}

Coté client :

IClient.cs
namespace Client
{
    interface IClient
    {
        bool Connect(string adresse, ushort port);
        void Disconnect();
    }
}
IClientImpl.cs
namespace Client
{
    interface IClientImpl : IClient, IServeurFonctions
    {
    }
}

Client

ClientTcp.cs
namespace Client
{
    class ClientTcp : IClient, IDisposable
    {
        private TcpClient _tcpClient = new TcpClient();
        protected Stream StreamClient { get; private set; }
 
        public bool Connect(string adresse, ushort port)
        {
            if (StreamClient != null)
                return false;
            try
            {
                _tcpClient.Connect(adresse, port);
            }
            catch (SocketException e)
            {
                if (e.SocketErrorCode == SocketError.ConnectionRefused)
                    return false;
                throw;
            }
            StreamClient = _tcpClient.GetStream();
            return true;
        }
 
        public void Disconnect()
        {
            _tcpClient.Close();
            StreamClient?.Dispose();
            StreamClient = null;
        }
 
        #region IDisposable Support
        private bool disposedValue = false; // To detect redundant calls
 
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    _tcpClient.Close(); // Dispose inaccessible.
                    StreamClient?.Dispose();
                }
 
                // Free unmanaged resources (unmanaged objects) and override a finalizer below.
                // Set large fields to null.
 
                disposedValue = true;
            }
        }
 
        // Override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
        // ~AClient() {
        //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
        //   Dispose(false);
        // }
 
        // This code added to correctly implement the disposable pattern.
        public void Dispose()
        {
            // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
            Dispose(true);
            // Uncomment the following line if the finalizer is overridden above.
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}
ClientArretPosteTcp.cs
namespace Client
{
    class ClientArretPosteTcp : ClientTcp, IClientImpl
    {
        public bool ArretPoste()
        {
            byte[] ArretPoste = Encoding.ASCII.GetBytes("ArretPoste");
            StreamClient.Write(ArretPoste, 0, ArretPoste.Length);
            byte[] bytes = new byte[1500];
            int nbOctets = StreamClient.Read(bytes, 0, 1500);
            string recu = Encoding.ASCII.GetString(bytes, 0, nbOctets);
            if (recu == "OK")
                return true;
            return false;
        }
    }
}

Serveur

ServeurTcp.cs
namespace Serveur
{
    abstract class ServeurTcp : IServeur
    {
        private TcpListener _serveur;
 
        public bool Connect(ushort port)
        {
            try
            {
                _serveur = new TcpListener(IPAddress.Any, port);
                _serveur.Start();
            }
            catch (SocketException e)
            {
                if (e.SocketErrorCode == SocketError.AddressAlreadyInUse)
                    return false;
                throw;
            }
            return true;
        }
 
        protected abstract Action<object> Pooling { get; }
 
        public void Join()
        {
            try
            {
                while (true)
                {
                    TcpClient client = _serveur.AcceptTcpClient();
                    ThreadPool.QueueUserWorkItem((objet) => Pooling(objet), new Tuple<TcpClient, IServeur>(client, this));
                }
            }
            catch (SocketException e)
            {
                // On ignore les erreurs d'interruption d'écoute.
                if (e.SocketErrorCode != SocketError.Interrupted)
                {
                    throw;
                }
            }
        }
 
        public void StopListening()
        {
            _serveur.Stop();
        }
    }
}
ServeurStopPCTcp.cs
namespace Serveur
{
    class ServeurStopPCTcp : ServeurTcp, IServeurImpl
    {
        private const int WM_USER = 0x0400;
 
        public bool ArretPoste()
        {
            Process.Start("shutdown","/s /t 0");
 
            return true;
        }
 
        protected override Action<object> Pooling { get { return AsyncClient.Connection; } }
 
        private static class AsyncClient
        {
            public static void Connection(object obj)
            {
                Tuple<TcpClient, IServeurImpl> data = (Tuple<TcpClient, IServeurImpl>)obj;
                TcpClient client = data.Item1;
                IServeurImpl serveur = data.Item2;
 
                NetworkStream stream = client.GetStream();
                AsyncCallback callback = new AsyncCallback(DonneesRecues);
                byte[] bytes = new byte[1500];
                stream.BeginRead(bytes, 0, bytes.Length, DonneesRecues, new Tuple<NetworkStream, byte[], IServeurImpl>(stream, bytes, serveur));
            }
 
            private static void DonneesRecues(IAsyncResult ar)
            {
                Tuple<NetworkStream, byte[], IServeurImpl> data = (Tuple<NetworkStream, byte[], IServeurImpl>)ar.AsyncState;
                NetworkStream stream = data.Item1;
                int nbOctets = stream.EndRead(ar);
                byte[] bytes = data.Item2;
                string commande = Encoding.ASCII.GetString(bytes, 0, nbOctets);
 
                IServeurImpl serveur = data.Item3;
                if (commande == "ArretPoste")
                {
                    if (serveur.ArretPoste())
                        bytes = Encoding.ASCII.GetBytes("OK");
                    else
                        bytes = Encoding.ASCII.GetBytes("NOK");
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Close();
                    serveur.StopListening();
                }
                else
                {
                    // On lance l'acquisition du paquet suivant.
                    stream.BeginRead(bytes, 0, bytes.Length, DonneesRecues, new Tuple<NetworkStream, byte[], IServeur>(stream, bytes, serveur));
                }
            }
        }
    }
}

HTTP / HTTPS

using System;
using System.IO;
using System.Net;
using System.Text;
 
// Données à transmettre en POST
string post_data = "command=UPSSLEEP&shutofftype=4";
 
// A l'URL ci-dessous.
string uri = "https://localhost:6547/REST/upssleep";
 
// Définition des paramètres de connexion.
// Utilisation de TLS1.2. Nécessaire si la configuration par défaut n'est pas bonne.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
// Autoriser les certificats invalides.
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
 
// Création de la requête
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Credentials = new NetworkCredential("user", "pass");
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version11;
request.Method = "POST";
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
 
// Initialisation de la connexion
using (Stream requestStream = request.GetRequestStream())
{
    // Et envoie des données.
    requestStream.Write(postBytes, 0, postBytes.Length);
}
 
// On récupère la réponse.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
lang/csharp/net/client_serveur.txt · Dernière modification : 2019/01/23 18:02 de root