=====TCP===== ====TcpClient==== ===Les interfaces=== Les fonctionnalités du serveur sont dans une ''Class Library'' à part et commune aux projets client / serveur. namespace Common { public interface IServeurFonctions { bool ArretPoste(); } } Coté serveur : namespace Serveur { interface IServeur { bool Connect(ushort port); void Join(); void StopListening(); } } namespace Serveur { interface IServeurImpl : IServeur, IServeurFonctions { } } Coté client : namespace Client { interface IClient { bool Connect(string adresse, ushort port); void Disconnect(); } } namespace Client { interface IClientImpl : IClient, IServeurFonctions { } } ===Client=== 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 } } 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=== 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 Pooling { get; } public void Join() { try { while (true) { TcpClient client = _serveur.AcceptTcpClient(); ThreadPool.QueueUserWorkItem((objet) => Pooling(objet), new Tuple(client, this)); } } catch (SocketException e) { // On ignore les erreurs d'interruption d'écoute. if (e.SocketErrorCode != SocketError.Interrupted) { throw; } } } public void StopListening() { _serveur.Stop(); } } } 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 Pooling { get { return AsyncClient.Connection; } } private static class AsyncClient { public static void Connection(object obj) { Tuple data = (Tuple)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(stream, bytes, serveur)); } private static void DonneesRecues(IAsyncResult ar) { Tuple data = (Tuple)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(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);