Jeden socket bidirectional czy dwa osobne sockety?

0

Załóżmy że mam do napisania system czas rzeczywistego w którym poszczególne komponenty komunikują się przez sieć (będzie to komunikacja peer-to-peer po UDP). Komponenty muszą wysyłać nawzajem do siebie ciągły strumień danych. Czy w tym przypadku lepiej skorzystać z jednego socket'u i tam naprzemiennie wysyłać/odbierać paczki (a może sockety umożliwiają wysyłkę/obiór paczek jednocześnie?), czy może między komponentem A i B otworzyć dwa socket'y, jeden służący do wysyłki strumienia danych od A do B, drugi służący do wysyłki strumienia danych od B do A, a może nie ma to żadnego znaczenia ze względów wydajnościowych? Dodam, że strumień danych, który wysyła komponent A do komponentu B jest całkowicie niezależny od strumienia który wysyła komponent B do A.

4

Jak będziesz miał dwa wątki i dwa różne sockety to na pewno to będzie bardziej wydajne niż jeden socket na jednym wątku

0

Z innych socketów jest wątpliwe, czy będzie przechodzić przez firewalle ... o ile to jest taki case

Po drugie, nie wyobrażam sobie socketa zupełnie jednokierunkowego. A gdzie handshaking?

2

Dwa sockety zdecydowanie lepiej w tym przypadku.

1

A, a może nie ma to żadnego znaczenia ze względów wydajnościowych?

Raczej nie ma znaczenia. Zwłaszcza jeśli zastosujesz jakiś event loop. Wydajnościowo powinno być tak samo, bo i tak raczej będzie Ciebie ograniczać IO, a nie czas CPU. Ja bym użył jednego socketa, bo łatwiej i wygodniej to w taki sposób zrobić (zwłaszcza z event loopem).

2

Nie rozumiem przedmówców. Możesz m.in. stworzyć jeden socket, i jednocześnie czytać i pisać do niego z dwóch wątków.

0

@enedil: własnie widziałem w dokumentacji MSDN: https://docs.microsoft.com/en[...]ckets.socket?view=netcore-3.1, że klasa Socket jest thread-safe, zastanawia mnie jednak jak to wygląda od strony wydajnościowej, jeżeli mogę jednocześnie czytać i pisać z jednego socketu to będzie to tak samo wydajne jak dwa osobne sockety w osobnych wątkach?

@hauleth: mógłbyś sprecyzować co masz na myśli pisząc event loop, czy chodzi Ci po prostu o użycie asynchronicznych metod do wysyłki/odbioru tak, żeby nie blokować programu?

1

mógłbyś sprecyzować co masz na myśli pisząc event loop, czy chodzi Ci po prostu o użycie asynchronicznych metod do wysyłki/odbioru tak, żeby nie blokować programu?

Nie napisałeś w jakim języku pracujesz, więc możliwe, że "asynchronicznych metod" nie ma. Można tutaj np. słuchać na jednym sockecie, ale faktyczną pracę robić już w osobnych wątkach i to z tych wątków odpowiadać. Wszystko zależy co i jak chcesz osiągnąć, oraz jakie narzędzia daje Ci sam język.

2

Jeśli chodzi o wydajność, to niestety nie wiem, moja odpowiedź była bazowana na doświadczeniu z Linuksem (i nieco przypadkiem się zdarzyło, że na Windowsie też działa). W kwestii event loop, są biblioteki, które upraszczają synchroniczne operacje na sieciach - możesz jednocześnie czekać na możliwość przeczytania i wysłania danych, i gdy zdarzy się event (np. że możesz czytać), to uruchamiany jest zarejestrowany przez Ciebie handler. Przykładami takich bibliotek jest libevent czy libuv (dla C/C++, ale na nich też bazują implementacje w innych językach).

3

Wydajność
Uważam to za niepoprawne stwierdzenie, że dwa sockety na dwóch wątkach są bardziej wydajne nie mając szerszego kontekstu. Czy dane wysyłane i odczytywane są synchronizowane ze sobą? W takim wypadku być może posiadanie 2 gniazd na 2 wątkach (czy też 2 wątków i 1 socketa) jedynie pogorszy wydajność , bo dojdzie mechanizm synchronizacji pomiędzy nimi. Podczas gdy epoll/poll/select/kqueue na jednym gnieździe wyeliminuje konieczność synchronizacji pomiędzy wątkami, bo całość danych będzie modyfikowana tylko z jednego wątku.
Kolejną kwestią jest wąskie gardło. Czy są to obliczenia czy być może wejście/wyjście? Jeżeli jest to wejście/wyjście, to dwa wątki nie pomogą, nie przyśpieszą komunikacji sieciowej. Dwa wątki mogą przyśpieszyć kolejkowanie i konsumowanie danych z bufora jądra systemu (de facto nieblokujące gniazda zapewnią to samo), pytanie jednak czy nie jest tak, że i/o karty sieciowej jest wolniejsze od samego przetwarzania już otrzymanych danych i buforowania nowych do wysłania.
Czy wiesz ile czasu potrzeba na przetworzenie otrzymanych danych? Jeżeli mówimy o szybkich operacjach przetwarzania, to 1 nieblokujący socket może okazać się wydajniejszy.
Można też zadać sobe pytanie czy dane są przetwarzane od razu, czy są kolejkowane i przetwarzane później przez jeszcze inny wątek?

Język programowania
Jaki model komunikacji sieciowej oferuje język programowania? Niskopoziomowe operacje na socketach? Model aktorów? Pętla zdarzeń? Nie ma co walczyć z językiem.

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