Kolejność tworzenia strumieni.

0

Do dzisiejszego poranka nie przywiązywałem do kolejności tworzenia strumieni. Miałem taki kod:

socket = new Socket(host, port);                     
inStream = new ObjectInputStream(socket.getInputStream());
outStream = new ObjectOutputStream(socket.getOutputStream());

który - jak zobaczyłem w debuggerze - zawisał na tworzeniu inStream.
Po zamianie na

socket = new Socket(host, port);
outStream = new ObjectOutputStream(socket.getOutputStream());
inStream = new ObjectInputStream(socket.getInputStream());

program działa. Da się to jakoś wytłumaczyć?

1

Dokumentacja to przewiduje, ObjectInputStream(InputStream):

A serialization stream header is read from the stream and verified.

0

Jak napisałem, wcześniej nie zwracałem uwagi na kolejność. Obejrzałem kilkanaście swoich wcześniejszych programów, część miała kolejność Output => Input, część Input => Output, wszystkie działały!. Czyżby UB?

0

@tampir, kilka sprawdziłem dzisiaj.
Kod z pierwszego postu jest z pary programów: klient serwer. Kodu serwera nie zmieniałem, serwer działa z kodem:

in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());

Klient i serwer różnią się sposobem tworzenia soketu, w kliencie new Socket(...), w serwerze serverSocket.accept().

0

Przepraszam za objętość wiadomości, ale nie chcę bardziej namieszać.

Czyli taki kod w bieżącym programie powoduje blokadę?

Klient:

in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());

Serwer:

in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());

A taki kod w bieżącym programie wykonuje się zgodnie z oczekiwaniami?

Klient:

out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());

Serwer:

in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());

Dla mnie działanie drugiej wersji wydaje się logiczne, bo w momencie jak serwer tworzy swój strumień wejściowy, to strumień wyjściowy klienta już istnieje i zgodnie z tym, co jest napisane w dokumentacji blokada nie następuje. Póżniej serwer utworzy swój strumień wyjściowy i klient też będzie mógł utworzyć własny strumień wejściowy.

(...) nie przywiązywałem do kolejności tworzenia strumieni.

To znaczy, że tworzyłeś je w losowej kolejności, czy zawsze w tej samej, ustalonej?

Jeżeli w Twoich poprzednich programach zawsze masz pierwszą wersję kodu wymienioną wyżej i wszystko działa bez blokady, a w bieżącym programie występuje blokada, to faktycznie jest to dziwne.

0
bogdans napisał(a):

[...] Obejrzałem kilkanaście swoich wcześniejszych programów

Ale co my mamy wyjaśniać? Nie widzimy tych kilkunastu programów, więc trudno coś o nich powiedzieć. Pokaż jeden program, którego działania nie rozumiesz, który czymś zadziwia.

Na razie widzieliśmy, że jak próbujemy czytać z socketa, do którego nikt nie pisze, to program się zawiesza. To nas nie dziwi.

Generalnie odczyt i zapis robi się w osobnych wątkach i wtedy nic się nie blokuje. Albo korzysta się z jakichś innych mechanizmów synchronizacji zdarzeń, np. callbacków.

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