Wpis z mikrobloga

#csharp #programowanie

Uczę się dopiero i chciałem napisać prosty komunikator oparty o UDP. Tylko, że wyskakuje mi błąd "operacja nie jest dozwolona w gniazdach niepołączonych" w linijce 31.

http://pastebin.com/McGWAsDV

Jeszcze jakby ktoś poświęcił chwilę i napisał o dobrych praktykach w C# i co można było napisać lepiej, to byłbym wdzięczny.
  • 19
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@Maav: po co robisz opakowanie na klase UdpClient skoro nie ma ono zadnego wejscia? jezeli juz starasz sie korzystac z jakichs wzorcow to rob to dokladnie ...funkcja Send powinna miec w najgorszym przypadku 2 argumenty wejsciowe - wiadomosc oraz adres

// klasa UdpClient posiada warunkowa metode - Connect
  • Odpowiedz
  • 1
@Maav: dodaj tag #codereview,

UDP bez konkretnego połączenia wysyła wiadomość wchuj czyli nigdzie. Po drugie, jak na styl, zrobiłbym odrębną klasę np. Server i Client i dodałbym zdarzenia. Dzięki temu będziesz mógł elastycznie zarządzać kodem, podpinając różne metody pod zdarzenia.

Zalecałbym użycie TCP, bo UDP w tym przypadku to jest jak działo na komara - szybkość przesyłu jest większa niż bezpieczeństwo. Chaty nie potrzebują takiej szybkości więc
  • Odpowiedz
@japer: Ja tu się uczę dopiero ;P

#codereview miało być chyba do chwalenia się kodem. Ja się tego kodu wstydzę i chcę poprawić żeby działał.

Na razie poprawiłem na tyle: http://pastebin.com/hZaCnTUv .

Nie jestem teraz w stanie sprawdzić, czy działa wysyłanie/ odbieranie, ale nie wywala błędów. Jedyny problem jest taki, że po wpisaniu "/exit" się nie wyłącza, tak jak chciałem.
  • Odpowiedz
@Maav:

Po pierwsze: dlaczego dziedziczysz po klasie program? Jaki to ma sens? Klasa do odbierania i wysyłania wiadomości nie ma z nią nic wspólnego. W funkcji Main powinieneś po prostu używać tej klasy (i tak robisz, więc dziedziczenie nie ma większego sensu). Korzystasz w klasie bazowej z klasy, która po niej dziedziczy co na pewno nie jest dobrą praktyką.

Po drugie: na moje oko to są dwie różne klasy, jedna wysyła,
  • Odpowiedz
@Yahoo_: 1. Masz absolutna racje. 2. Pozwalało mi to posługiwać sie wspólnymi zmiennymi np. IP 3. Funkcja Check wywołuje sie rekurencyjnie, ponieważ np. po wpisaniu '/help' użytkownik moze zachciec zmienić IP i wtedy należy ponownie sprawdzić czy wiadomość nie jest komenda, a nie właściwą wiadomością. Nie miałem pomysłu jak to inaczej rozwiązać bez rekurencji.
  • Odpowiedz
@Maav: moim zdaniem powinieneś dążyć do mnie więcej takiego wyglądu funkcji do wysyłania i odbierania.

Klasa nie powinna być odpowiedzialna za pobieranie od użytkownika danych (zgodnie z "Don't look for things. Ask for them!"). To czyni ją kompletnie niereużywalną. To samo przy odebraniu wiadomości. Rzucasz tylko event, a zainteresowani mogą robić co chcą z otrzymaną wiadomością. Nawet samo HandleCommand mogło by być poza klasą (to chyba byłby dobry pomysł), może
  • Odpowiedz
@Maav: Się uparłeś na te wątki stawiane własnoręcznie :P. Skorzystaj z ThreadPool, to bardziej eleganckie rozwiązanie na moje :).

catch(e)
  • Odpowiedz
@Maav: Co do adresu w formie słownej: rozumiem, że jak korzystałeś z konstruktora, który przyjmował hostname i port to działało? To akurat najmniejszy problem po prostu trzymaj te dane zamiast IPEndPoint (wtedy Send przyjmie 3 parametry msg, host i port). Ewentualnie zabawa z jakimś parserem i rozpoznawać w jakiej formie podano adres. Przeczuć obsługę reakcji na odebranie wiadomości do eventu, żebyś nie był uzależniony od konsoli. Nie bardzo rozumiem czemu
  • Odpowiedz