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

Przesyłanie wiadomości pomiędzy klientem/serwerem TCP

VPS Starter Arubacloud
0 głosów
341 wizyt
pytanie zadane 22 kwietnia 2022 w C# przez muzyk Użytkownik (940 p.)

Witam serdecznie. 

Potrzebuję pomocy przy przesyłaniu wiadomosci pomiędzy serwerem i klientem TCP.

Stworzyłem formularz Windows, który ma pola na adres IP i port. Po kliknięciu przycisku Start uruchamia się serwer TCP. Aktywowany jest BackgroundWorker, który oczekuje na połączenia od klientów. Gdy ten się połączy zostaje zaakceptowany i uruchamia się kolejny backgroundWorker odpowiedzialny za pomieranie danych z bufora (Metoda ReadLine()).

 

Z kolei w formularzu klienta na sztywno podałem adres IP jaki mam przypisany w sieci lokalnej na serwerze. Łączę się z serwerem, a jeżeli połączenie zostanie ustanowione wysyłam wiadomosć. 

 

Problem w tym, że serwer nie odbiera tej wiadomosci. Kod poniżej.

Serwer:

Po kliknięciu w przycisk "Start":

      private void buttonStart_Click(object sender, EventArgs e)
        {
            addres = textBoxPortNumber.Text;

            listener = new TcpListener(locals, int.Parse(addres));
            listener.Start();
            backgroundWorkerConnectingUsers.RunWorkerAsync();

        }

 

backgroundWorkerConnectingUsers:

     private void backgroundWorkerConnectingUsers_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                     if (listener.Pending()) // Prawdiwe, gdy w kolejce oczekuje host do podłączenia
                    {
                        client = listener.AcceptTcpClient();
                        STR = new StreamReader(client.GetStream());
                        STW = new StreamWriter(client.GetStream());
                        backgroundWorkerReceiveMessage.RunWorkerAsync();
                    }
              
            }
        }

 

backgroundWorkerReceiveMessage:

        private void backgroundWorkerReceiveMessage_DoWork(object sender, DoWorkEventArgs e)
        {
         while (client.Connected)
            {
                try
                {
                    this.richTextBoxLogs.Invoke(new MethodInvoker(delegate ()
                    {
                        richTextBoxLogs.AppendText(STR.ReadLine() + "\n");
                    }));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

 

Kod po stronie klienta:

        private void butLogin_Click(object sender, EventArgs e)
        {
            TcpClient tcpClient = new TcpClient();
            IPAddress address = IPAddress.Parse("192.168.0.2");

            tcpClient.Connect(address, 1234);

            sw = new StreamWriter(tcpClient.GetStream());

            if(tcpClient.Connected)
            sw.WriteLine("HelloWorld!");
}

 

Z tego co rozumiem to w polu tekstowym richTextBoxLogs powienien się pojawić napis "HelloWorld"? W którym miejscu popełniam błąd? 

 

komentarz 22 kwietnia 2022 przez Oscar Nałogowiec (29,320 p.)
edycja 22 kwietnia 2022 przez Oscar

Nie znam C# więc nie powiem gdzie jest źle, ale kilka porad:

Przede wszystkim - nie staraj się uruchomić wszystkiego naraz.

masz polecenie netstat - możesz sprawdzić czy i jak otwierasz port serwerowy.

użyj różnych programów, które mogą działać jako serwer albo klient TCP i najpierw połącz się nimi lub z nimi. Np. telnet. Klientem możesz połączyć się z dowolnym serwerem np. pocztowym - protokół SMTP działa tak, że serwer od razu po połączeniu klienta przedstawia się.

$ nc smtp.gmail.com 25
220 smtp.gmail.com ESMTP m1-20020a05651202e100b0046cd451b8easm224220lfq.22 - gsmtp

Akurat użyłem nc bo mam Linuxa, ale telnet też działa.

Do swojego serwera, jak już netstat pokaże, że masz otwarty port nasłuchujący też możesz podłączyć się telnetem.

PS. Trochę nie podoba mi się pętla czekania na klientów - w czasie gdy nikt się nie łączy (Pending() daje false) robisz puste pętle.

1 odpowiedź

+2 głosów
odpowiedź 22 kwietnia 2022 przez PH03NIX Mądrala (6,130 p.)
wybrane 25 kwietnia 2022 przez muzyk
 
Najlepsza

Spróbuj po sw.WriteLine(); w kliencie dać:

sw.Flush();

 

komentarz 25 kwietnia 2022 przez muzyk Użytkownik (940 p.)

Pomogło. Dziękuję serdecznie.
 

Zostawiam dla potrzebujących:
Microsoft.doc Flush()

Podobne pytania

0 głosów
0 odpowiedzi 287 wizyt
+2 głosów
1 odpowiedź 212 wizyt
pytanie zadane 17 września 2017 w Sieci komputerowe, internet przez Hapsiu Użytkownik (510 p.)
0 głosów
0 odpowiedzi 1,340 wizyt
pytanie zadane 7 lipca 2020 w C# przez MultiWu Nowicjusz (120 p.)

92,839 zapytań

141,780 odpowiedzi

320,848 komentarzy

62,171 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

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!

...