using System.Net; using System.Net.Sockets; using System.Text; namespace Server; class Program { private const int Porta = 1322; private const int TimeoutLetturaMs = 5 * 60 * 1000; static void Main(string[] args) { Console.WriteLine("Hello, Server!"); TcpListener? listener = null; Encoding utf8SenzaBom = new UTF8Encoding(false); try { IPAddress localAddr = IPAddress.Parse("127.0.0.1"); listener = new TcpListener(localAddr, Porta); listener.Start(); Console.WriteLine("Server avviato."); while (true) { using TcpClient client = listener.AcceptTcpClient(); try { client.ReceiveTimeout = TimeoutLetturaMs; using NetworkStream stream = client.GetStream(); using StreamReader reader = new StreamReader(stream, utf8SenzaBom); using StreamWriter writer = new StreamWriter(stream, utf8SenzaBom); writer.AutoFlush = true; //writer.WriteLine("[CONNESSO] Scrivi 'exit' per chiudere"); sendMsg("[CONNESSO] Scrivi 'exit' per chiudere", stream); string? messaggioDalClient; //while ((messaggioDalClient = reader.ReadLine()) != null) while ((messaggioDalClient = recieveMsg(stream)) != null) { Console.WriteLine("[Client] " + messaggioDalClient, stream); if (messaggioDalClient.Trim().Equals("exit")) { //writer.WriteLine("[ADDIO]"); sendMsg("[ADDIO]", stream); break; } if (messaggioDalClient.StartsWith("/add")) { try { string[] parti = messaggioDalClient.Split(" "); //writer.WriteLine( // int.Parse(parti[1]) + // int.Parse(parti[2])); sendMsg( (int.Parse(parti[1]) + int.Parse(parti[2])).ToString(), stream); } catch (Exception) { //writer.WriteLine("Muori, fai schifo."); sendMsg("Muori fai schifissimo", stream); } } else { //writer.WriteLine("[SERVER] Messaggio ricevuto -> " + messaggioDalClient); sendMsg("[SERVER] Messaggio ricevuto -> " + messaggioDalClient, stream); } } if (messaggioDalClient == null) { Console.WriteLine("Client è morto"); } } catch (IOException e) { SocketException? causa = e.InnerException as SocketException; if (causa != null && causa.SocketErrorCode == SocketError.TimedOut) { Console.WriteLine("Time out"); } else { Console.WriteLine("Connessione terminata dal server: " + e.Message); } Console.WriteLine(e.Message); } catch (SocketException e) { Console.WriteLine("errore di rete: " + e.Message); switch (e.SocketErrorCode) { case SocketError.ConnectionRefused: Console.WriteLine("Connessione rifiutata dal server"); break; case SocketError.HostNotFound: Console.WriteLine("Host non trovato"); break; case SocketError.TimedOut: Console.WriteLine("Time out"); break; default: Console.WriteLine(e.SocketErrorCode.ToString()); break; } } catch (Exception e) { Console.WriteLine("Errore: " + e.Message); } Console.WriteLine("Connessione terminata"); } } catch (SocketException e) { switch (e.SocketErrorCode) { case SocketError.AddressAlreadyInUse: Console.WriteLine("Indirizzo in uso"); break; case SocketError.AccessDenied: Console.WriteLine("non te lo puoi permettere"); break; default: Console.WriteLine("Errore: " + e.Message); break; } } catch (Exception e) { Console.WriteLine("Errore: " + e.Message); } finally { if (listener != null) { try { listener.Stop(); Console.WriteLine("Server Terminato"); } catch (SocketException e) { Console.WriteLine("Errore nello spegnimento server: " + e.Message); } } Console.WriteLine("Premi un tasto per chiudere"); Console.ReadKey(); } } public static string sendMsg(string messaggio, NetworkStream stream) { int dimMax = 1024 * 1024; int lungHeadMsg = 4; if (messaggio == null) throw new ArgumentNullException(nameof(messaggio)); try { byte[] corpo = Encoding.UTF8.GetBytes(messaggio); if (corpo.Length > dimMax) return "Messaggio troppo lungo"; byte[] header = BitConverter.GetBytes(corpo.Length); byte[] pacchetto = new byte[lungHeadMsg + corpo.Length]; Buffer.BlockCopy(header, 0, pacchetto, 0, lungHeadMsg); Buffer.BlockCopy(corpo, 0, pacchetto, lungHeadMsg, corpo.Length); stream.Write(pacchetto, 0, pacchetto.Length); return "Messaggio inviato"; } catch (Exception) { return "Errore nell'invio del messaggio"; } } public static string recieveMsg(NetworkStream stream) { int dimMax = 1024 * 1024; int lungHeadMsg = 4; if (stream == null) throw new ArgumentNullException(nameof(stream)); try { byte[] header = new byte[lungHeadMsg]; if (!leggiByteDaStream(stream, header, header.Length)) return "connessione chiusa prima di poter leggere"; int lunghezza = BitConverter.ToInt32(header, 0); if (lunghezza < 0 || lunghezza > dimMax) return "Lunghezza non valida"; byte[] corpo = new byte[lunghezza]; if (!leggiByteDaStream(stream, corpo, corpo.Length)) return "connessione chiusa prima di poter leggere"; return Encoding.UTF8.GetString(corpo); } catch (Exception) { return "errore"; } } private static bool leggiByteDaStream(NetworkStream stream, byte[] buffer, int length) { int letti = 0; while (letti < length) { int n = stream.Read(buffer, letti, length - letti); if (n == 0) return false; letti += n; } return true; } }