• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Aplikacja klient serwer nie działa prawidłowo

Object Storage Arubacloud
0 głosów
210 wizyt
pytanie zadane 26 marca 2017 w C# przez timrh Mądrala (6,030 p.)

Witam mam problem, otóż napisałem aplikację kliencką:

 

using System.Net.Sockets;
using System.Net;
using System.IO;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Client
{
    class Program
    {
        private static TcpClient    client = new TcpClient();
        private static StreamReader reader;
        private static StreamWriter writer;

        private static bool         refresh;
        private static List<string> messages = new List<string>();

        public static void Main()
        {
            Console.Title = "Client";
            
            do //try to connect
            {
                Console.WriteLine("Connecting to server...");

                try
                {
                    client.Connect(IPAddress.Parse("127.0.0.1"), 8080);
                }
                catch (SocketException) { }

                Thread.Sleep(10);
            } while (!client.Connected);
            
            // \/ CONNECTED \/

            Console.WriteLine("Connected.");

            reader = new StreamReader(client.GetStream());
            writer = new StreamWriter(client.GetStream());

            var sendTask       = Task.Run(() => SendMessage());          //task for sending messages
            var recieveTask    = Task.Run(() => RecieveMessage());       //task for recieving messages
            var updateConvTask = Task.Run(() => UpdateConversation());   //task for update console window

            Task.WaitAll(sendTask, recieveTask); //wait for end of all tasks
        }

        private static void SendMessage()
        {
            string msgToSend = string.Empty;
            do
            {
                Console.WriteLine("Enter a message to send to the server");
                msgToSend = Console.ReadLine();
                writer.WriteLine(msgToSend);
                writer.Flush();
            } while (!msgToSend.Equals("Exit"));
            EndConnection();
        }

        private static void RecieveMessage()
        {
            try
            {
                while (client.Connected)
                {
                    //Console.Clear();
                    string msg = reader.ReadLine();

                    if(msg != string.Empty)
                    {
                        if (msg == "%C") //special message from server, clear messages if recieve it
                        {
                            messages.Clear();
                        }
                        else
                        {
                            messages.Add(msg);
                            refresh = true; //refresh console window
                        }
                    }
                    //Console.Clear();
                    //Console.WriteLine(msgFromServer);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private static void UpdateConversation()
        {
            //string conversationTmp = string.Empty;

            try
            {
                while (true)
                {
                    if (refresh) //only if refresh
                    {
                        refresh = false;
                        Console.Clear();
                        messages.ForEach(msg => Console.WriteLine(msg)); //write all messages
                        Console.WriteLine();
                    }
                }
            }
            catch (Exception) { }
        }

        private static void EndConnection()
        {
            reader.Close();
            writer.Close();
            client.Close();
        }

    }
}

Oraz serwerową:

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Server
{
    class Program
    {
        private static List<Client> clients = new List<Client>();
        private static TcpListener  listener = null;
        private static StreamReader reader = null;
        private static StreamWriter writer = null;
        private static List<Task>   clientTasks = new List<Task>();
        private static List<string> messages = new List<string>();

        public static void Main()
        {
            Console.Title = "Server";
            try
            {
                listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8080);
                listener.Start();
                Console.WriteLine("Server started...");

                var connectTask = Task.Run(() => ConnectClients());
                //var listenTask = Task.Run(() => ListenClients());

                Task.WaitAll(connectTask);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                if (listener != null)
                {
                    listener.Stop();
                }
            }
        }

        private static void ConnectClients()
        {
            Console.WriteLine("Waiting for incoming client connections...");
            while (true)
            {
                if (listener.Pending()) //if someone want to connect
                {
                    clients.Add(new Client(listener.AcceptTcpClient(), "Client: " + (clients.Count + 1)));
                    Console.WriteLine(clients[clients.Count - 1].clientName + " connected to server.");
                    clientTasks.Add(Task.Run(() => HandleClient(clients[clients.Count - 1]))); //start new task for new client
                }
            }
        }

        private static void HandleClient(Client TCPClient)
        {
            string s = string.Empty;
            writer = new StreamWriter(TCPClient.client.GetStream());
            reader = new StreamReader(TCPClient.client.GetStream());

            try
            {
                while (!(s = reader.ReadLine()).Equals("Exit") || (s == null))
                {
                    if(!TCPClient.client.Connected)
                    {
                        Console.WriteLine("Client disconnected.");
                        clients.Remove(TCPClient);
                    }

                    Console.WriteLine("From client: " + TCPClient.clientName  + " -> " + s);
                    messages.Add(TCPClient.clientName + ": " + s); //save new message
                    //Console.WriteLine(s);

                    foreach (Client c in clients) //refresh all connected clients
                    {
                        c.writer.WriteLine("%C"); //clear client
                        foreach (string msg in messages)
                        {
                            c.writer.WriteLine(msg);
                            c.writer.Flush();
                        }
                    }
                }
                CloseServer();
            }
            catch (Exception e) { Console.WriteLine(e); }
        }

        private static void CloseServer()
        {
            reader.Close();
            writer.Close();
            clients.ForEach(tcpClient => tcpClient.client.Close());
        }
    }
}

I klasę pomocniczą, Client:

 

using System.Net.Sockets;
using System.IO;

namespace Server
{
    class Client
    {
        public TcpClient client;
        public StreamWriter writer;
        public string clientName;

        public Client(TcpClient client, string clientName)
        {
            this.client = client;
            writer = new StreamWriter(client.GetStream());
            this.clientName = clientName;
        }
    }
}


Klienci wysyłają wiadomości do serwera który przechowuje całą konwersację, po otrzymaniu wiadomości wysyła całą konwersację do wszystkich klientów odświeżając tym samym ich okna.

Program działa dobrze dla jednego klienta, ale kiedy mam dwóch, na początku działa ale gdy jeden klient wyśle wiadomość, a potem drugi wyśle to tak jakby jeden z klientów pisze za dwóch raz za jednego raz za drugiego a drugi nie może napisać nic.

1 odpowiedź

–1 głos
odpowiedź 17 kwietnia 2017 przez pulson666 Stary wyjadacz (12,560 p.)
myślę, że asynchroniczność rozwiąże Twój problem
komentarz 17 kwietnia 2017 przez timrh Mądrala (6,030 p.)
A więc czym są twoim zdaniem Taski?
komentarz 18 kwietnia 2017 przez pulson666 Stary wyjadacz (12,560 p.)
a faktycznie przeoczyłem to, moja wina.

Podobne pytania

–1 głos
1 odpowiedź 789 wizyt
0 głosów
1 odpowiedź 438 wizyt
pytanie zadane 11 czerwca 2022 w Java przez romilus Nowicjusz (120 p.)
+1 głos
1 odpowiedź 688 wizyt
pytanie zadane 7 stycznia 2018 w C i C++ przez Kapi2222 Obywatel (1,220 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...