Wyświetlanie zawartości zmiennej

0

Witam serdecznie.
Pobrałem sobie przykład z Codeguru serwera socketowego: http://www.codeguru.pl/article-654.aspx

Po uruchomieniu serwera i 1/2/3/.. klientów wszystko chodzi pięknie.
Po dodaniu mojego kodu (w serwerze):

Console.WriteLine(dane);
wclient.WriteLine(dane);
wclient.Flush();

Program po zalogowaniu się i wpisaniu jakiegokoliwek tekstu w kliencie się wywala w lini: wclient.WriteLine(dane);

dostaje błąd:
NullReferenceException occured - Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.

Co robię nie tak?? Wiecie może jak wyświetlić w tym przykładzie komunikaty wprowadzane przez klientów w oknie serwera??

z góry dzieki za pomoc:))
Pozdrawiam

0

wclient jest nullem, ale czemu to nie wiadomo, bo nie ma wiecej kodu.

0

to jest kod stąd:

namespace Serwer
{
    //Struktura opisująca użytkownika
    structclientInfo
    {        publicString login;
        publicTcpClient tcpclient;
    }
    classProgram
    {
        staticvoidMain(string[] args)
        {
           int sPort = 2000;          //Port na którym bedzie nasłuchiwał serwer komunikatora
            Hashtable klienci = newHashtable();    //Lista zalogowanych klientów
            try
            {
                IPAddress ip = IPAddress.Parse("127.0.0.1");
                TcpListener serwer = newTcpListener(ip,sPort);
                serwer.Start();
                Console.WriteLine("Serwer is started");
                while (true)
                {
                   //Akceptujemy połączenie i tworzymy obiekt TcpClient
                   TcpClient client = serwer.AcceptTcpClient();
                    //Pobieramy strumień do komunikacji
                   NetworkStream nstream = client.GetStream();
                    StreamWriter streamw = newStreamWriter(nstream);
                    streamw.WriteLine("Witamy na serwerze komunikatora");
                    streamw.Flush();
                    StreamReader rstream = newStreamReader(nstream);
                    //Odczytujemy dane od klienta
                   String dane = rstream.ReadLine();
                    Console.WriteLine("odebrano : " + dane);
                    //jeżeli zaczyna się od /login
                   if ( dane.StartsWith("/login") )

                    {
                       //wycinamy login uzytkownika
                        String login = dane.Substring(7); 
 //tworzymy obiekt opisujący użytkownika
                        clientInfo clientinf = newclientInfo();
                        clientinf.login = login;
                        clientinf.tcpclient = client;
                       //Dodajemy do hashtable
                       klienci.Add(clientinf.login, clientinf);
                        //tworzymy nowy wątek obsługujący klienta
                        newThread(newThreadStart( newsesja(clientinf.login, client, klienci).run)).Start();
                   }
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("Błąd : " + se.Message);
            }
        }
    }
}

Kod klasy obsługującej sesję połączenia z uzytkownikiem

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections;
namespace Serwer
{
   classsesja 
    {
        privateString pseudo = null;
        privateTcpClient client;
        privateHashtable users;
        privateStreamReader rclient;
        privateStreamWriter wour;
        privateStreamWriter wclient;
        privateString dane = null;
        public sesja(String _pseudo, TcpClient _client, Hashtable _users)
        {
            this.pseudo = _pseudo;
            this.client = _client;
            this.users = _users;
        }
        publicvoid run()
        {
            //tworzymy strumienie do zapisu i odczytu danych
            rclient = newStreamReader(client.GetStream());
            wour = newStreamWriter(client.GetStream());
            while (true)
            {
                try
                {
                  //odczytujemy dane od uzytkownika
                    dane = rclient.ReadLine();
                    if (dane.StartsWith("/pseudo"))
                    {
                      pseudo = dane.Substring(8);
                       //pobieramy strukture opisującą uzytkownika o podanym pseudonimie
                        clientInfo info = (clientInfo)users[pseudo];
                        //jezeli uzytkownik jest podłączony to tworzymy strumien danych z jego gniazda
                            if ( info.tcpclient.Client.IsBound )
                              wclient = newStreamWriter(info.tcpclient.GetStream());
                            else
                                wour.WriteLine("Użytkownik się rozłączył");                  
                    }
                    elseif (dane.StartsWith("/quit"))
                    {
                        client.Close();  //rozlaczenie uzytkownika
                        users.Remove(pseudo); //usuniecie z listy
                    }
                    else
                    {  
                        wclient.WriteLine(dane);  //wyslanie danych do uzytkownika
                        wclient.Flush();
                    }
                }catch(SocketException se)

                {
                    Console.WriteLine("Błąd : " + se.Message);

                }
            }
        }
    }
}

wygląda wszystko okey, ale coś nie chce działać.... :/// niby banalne zadanie, ale jednak...:/

0

Jesli dane nie zaczna sie tekstem /pseudo, to wclient pozostanie null. Stad wclient.WriteLine spowoduje wyrzucenie wyjatku NullPointerException.

0

ogólnie chce zrobić wyświetlanie wiadomości tych które sobie userzy przesyłają na serwerze... dobrze kombinuje??

czyli jak byś to rozwiązał?? bo ja już nie mam pomysłów.. :/

0

Wszystko wyglada w porzadku, ale masz blad logiczny. Zakladasz, ze pierwsza wiadomoscia jaka przyjdzie od rclient jest '/pseudo'. Z jakiegos powodu nie zawsze sie tak dzieje. Wtedy pomijasz tworzenie i przypisanie obiektu do wclient. Przechodzisz przez 2 pierwsze ify (/pseuo i /quit) i starasz sie wyslac wiadomosc do wclient, ktorego nie ma (bo jest nullem). Na to zwroc uwage.

0

czyli muszę wyprowadzić :wclient = new StreamWriter(info.tcpclient.GetStream());
przed while nie??:)

potem rozszerzyć sesję o IP i nie wiem za bardzo co dalej/jak to zrobić...:/

ps. mogę się do Ciebie odezwać jakoś na priv??:)

0

Chyba za daleko wyjezdzasz myslami ;) Musisz po prostu jakos obsluzyc sytuacje awaryjne. Nie wiem jak do konca wyglada schemat dzialania Twojej aplikacji, ale zaklada, ze osoba 1 laczac sie podaje pseudo osoby, z ktora chce rozmawiac. Zalozmy teraz, ze zapomnisz tego wyslac i od razu wypisujesz cos do serwera, ale nie '/pseudo'.

W tym przypadku:

wclient.WriteLine(dane);  //wyslanie danych do uzytkownika

zakladasz, ze wclient jest i jest polaczony i w ogole ktos raczyl wyslac '/pseudo'. Ale to bledne zalozenie, stad najlatwiej bedzie zrobic cos takiego:

else
{
  if(wclient != null)
  {
    wclient.WriteLine(dane);  //wyslanie danych do uzytkownika
    wclient.Flush();
  }
  else
    wour.WriteLine("Prosze podac nazwe uzytkownika, z ktorym chcesz rozmawiac");
    // wysylajacy dostanie ten komunikat jesli nie wyslal jeszcze komunikatu 
/pseudo nazwa_uzytkownika
}
0

mogę się do Ciebie odezwać na email??:) chciałbym się dopytać cosik więcej...:) czy nie bardzo??

0

Jasne, albo podaj swoj numer gg.

0

4093167 :) dzięki!!

1 użytkowników online, w tym zalogowanych: 0, gości: 1