Thread View: pl.comp.lang.java
8 messages
8 total messages
Started by Artik
Sun, 09 Dec 2012 15:29
Java i automatyczne wznawianie połączenia klienckiego socket
Author: Artik
Date: Sun, 09 Dec 2012 15:29
Date: Sun, 09 Dec 2012 15:29
79 lines
3496 bytes
3496 bytes
Witam,
Czy mógłbym Was prosić o wskazanie sposobu obsłużenia błędu połączenia z serwerem tcp wykonywanym przez standardowe gdniazdo?
Próbuje to zrealizować tworząc dwa wątki - jeden - najważniejszy dla usługi - służy do wysylania cyklicznie danych do serwera, drugi thr1 sluży do sprawdzania czy nie było awarii w pierwszym wątku (socket polaczenia ustawiam na null w wyniku obsługi wyjątku błedu połączenia) i wówczas wywołuje metodę:
public Socket sock=null;
private BufferedReader r;
private BufferedWriter out;
...
public void stopSocket() {
try {
try{
if (r != null){
r.close();
r=null;
}
} catch (IOException e) {
Log.d("APLIKACJA", e.getMessage()+" "+e.getCause());
}
try{
if (out != null)
{
// sock.shutdownOutput();
out.close();}
out=null;
} catch (IOException e) {
Log.d("APLIKACJA", e.getMessage()+" "+e.getCause());
}
try{
if (sock != null){
sock.close();
sock=null;
}
catch (IOException e) {
Log.d("APLIKACJA", e.getMessage()+" "+e.getCause());
sock=null;
out=null;
r=null;
}
}
i probuje w watku sprawdzajacym poprawnosc polaczenia dokonać jego wznowienia:
thrd1 = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
}
if (sock==null)
try {
sock = new Socket();
sock.connect(new InetSocketAddress(
address, 5000), 1000);
if ((thrd2!=null)&&(!thrd2.isAlive()))
thrd2.start();
} catch (UnknownHostException e) {
stopSocket();
} catch (IOException e) {
stopSocket();
}
}
;
}
});
if ((thrd1!=null)&&(!thrd1.isAlive()))
thrd1.start();
}
});
}
Wznowienie nastepuje ale ponownie wlaczony serwer po przerwie - otrzymuje kilkanascie prob rozpoczęcia polaczenia ze strony przedstawionego klienta. Jak czas niedostępności serwera jest zbyt dlugi - aplikacja kliencka niestety "pada":(
Czy mogę liczyć na Waszą pomoc?
Artik
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Arivald
Date: Sun, 09 Dec 2012 17:11
Date: Sun, 09 Dec 2012 17:11
24 lines
2317 bytes
2317 bytes
W dniu 2012-12-09 16:29, Artik pisze:
> Witam,
> Czy mógłbym Was prosić o wskazanie sposobu obsłużenia błędu połączenia z serwerem tcp wykonywanym przez standardowe gdniazdo?
> Próbuje to zrealizować tworząc dwa wątki - jeden - najważniejszy dla usługi - służy do wysylania cyklicznie danych do serwera, drugi thr1 sluży do sprawdzania czy nie było awarii w pierwszym wątku (socket polaczenia ustawiam na null w wyniku obsługi wyjątku błedu połączenia) i wówczas wywołuje metodę:
> public Socket sock=null;
> private BufferedReader r;
> private BufferedWriter out;
> ...
> public void stopSocket() {
> try {
> try{
Spróbuj 4 albo lepiej 2 spacji wcięć.
>
> Wznowienie nastepuje ale ponownie wlaczony serwer po przerwie - otrzymuje kilkanascie prob rozpoczęcia polaczenia ze strony przedstawionego klienta. Jak czas niedostępności serwera jest zbyt dlugi - aplikacja kliencka niestety "pada":(
>
> Czy mogę liczyć na Waszą pomoc?
Czemu nie obsłużysz ponownego połączenia w tym samym wątku do wysyłanie
danych socketa, zaraz po otrzymaniu błędu? Tak się to zawsze robiło...
--
Arivald
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Artik
Date: Sun, 09 Dec 2012 17:24
Date: Sun, 09 Dec 2012 17:24
6 lines
1565 bytes
1565 bytes
> Czemu nie obsłużysz ponownego połączenia w tym samym wątku do wysyłanie > > danych socketa, zaraz po otrzymaniu błędu? Tak się to zawsze robiło... Ponieważ muszę też obsłużyć w kolejnym wątku odbiór danych od serwera, które nie zależą od wysyłanych do niego informacji więc nie mogą być obsługiwane synchronicznie:( Artik
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Arivald
Date: Sun, 09 Dec 2012 22:17
Date: Sun, 09 Dec 2012 22:17
16 lines
1911 bytes
1911 bytes
W dniu 2012-12-09 18:24, Artik pisze: >> Czemu nie obsłużysz ponownego połączenia w tym samym wątku do wysyłanie >> >> danych socketa, zaraz po otrzymaniu błędu? Tak się to zawsze robiło... > Ponieważ muszę też obsłużyć w kolejnym wątku odbiór danych od serwera, które nie zależą od wysyłanych do niego informacji więc nie mogą być obsługiwane synchronicznie:( > > Artik > A co do ma do rzeczy? Błąd socketa (rozłączenie) obsługujesz w tym samym wątku w którym nastąpił (np. łączysz się ponownie). A to że jeden wątek nadaje, drugi odbiera nie ma nic do rzeczy, każdy zajmuje się swoimi socketami. -- Arivald
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Artik
Date: Mon, 10 Dec 2012 06:00
Date: Mon, 10 Dec 2012 06:00
53 lines
4147 bytes
4147 bytes
Rozumiem, zrewidowałem swoje podejscie i teraz mam przykład kodu jak poniżej:
thrd3 = new Thread(new Runnable() {
@Override
public void run() {
Socket sock = null;
BufferedWriter out = null;
while (true) {
//chwila odpoczynku dla systemu
try {
Thread.sleep(1000);
} catch (InterruptedException e2) {
Thread.currentThread().interrupt();
}
//proba wyslania gdy socket ustawiony (1 proba nie zostanie podjeta - socket jeszcze nie ustawiony)
if (sock != null) {
try {
out.write("TEST DATA\n");
out.flush();
} catch (IOException e) {
//w przypadku bledu zamkniecie Socketa i BufferedWritera
// ERROR-----------------------
try {
out.close();
sock.close();
sock = null;
} catch (IOException e1) {
sock = null;
out = null;
}
}
} else
// jesli socket==null proba inicjowania lub reinicjowania polaczenia
{
try {
sock = new Socket();
sock.connect(new InetSocketAddress(address,
5000), 1000);
out = new BufferedWriter(
new OutputStreamWriter(sock
.getOutputStream()));
} catch (IOException e1) {
sock = null;
}
}
}
}
});
thrd3.start();
Ale dalej wystepuje problem kilku "uderzeń" inicjujących połączenie od klienta do serwera po włączeniu tego drugiego (im dłużej serwer jest niedostępny tym jest ich więcej). Nie rozumiem tego - myslę, że kiedy klient probuje sie polączyć i mu to nie wychodzi, podchodzi do kolejnej proby a wszystkie poprzednie "umierają"). Teraz to wygląda tak jakby oczekiwały one w tle. Nie wiem czy wyrażam wystarczająco przejrzyście, nie jestem z wykształcenia informatykiem.
Pozdrawiam
Artik
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Arivald
Date: Mon, 10 Dec 2012 10:14
Date: Mon, 10 Dec 2012 10:14
14 lines
2181 bytes
2181 bytes
W dniu 2012-12-10 07:00, Artik pisze: > Rozumiem, zrewidowałem swoje podejscie i teraz mam przykład kodu jak poniżej: [...]> > Ale dalej wystepuje problem kilku "uderzeń" inicjujących połączenie od klienta do serwera po włączeniu tego drugiego (im dłużej serwer jest niedostępny tym jest ich więcej). Nie rozumiem tego - myslę, że kiedy klient probuje sie polączyć i mu to nie wychodzi, podchodzi do kolejnej proby a wszystkie poprzednie "umierają"). Teraz to wygląda tak jakby oczekiwały one w tle. Nie wiem czy wyrażam wystarczająco przejrzyście, nie jestem z wykształcenia informatykiem. > Akurat nie wiem jak sockety w Javie działają, tzn jak się ma Javowa klasa Socket to rzeczywistego socketa systemu. Może przy próbie zamknięcia socketa tak naprawdę się on nie zamyka? Może rzuca wyjątek? W takim wypadku Twoja implementacja po prostu porzuca referencję do socketa, a on może ciągle działać. -- Arivald
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: TrzyLinie
Date: Mon, 10 Dec 2012 19:55
Date: Mon, 10 Dec 2012 19:55
31 lines
3074 bytes
3074 bytes
W dniu 2012-12-09 16:29, Artik napisał(a):
> Próbuje to zrealizować tworząc dwa wątki - jeden - najważniejszy dla usługi - służy do wysylania cyklicznie danych do serwera, drugi thr1 sluży do sprawdzania czy nie było awarii w pierwszym wątku (socket polaczenia ustawiam na null w wyniku obsługi wyjątku błedu połączenia) i wówczas wywołuje metodę:
W Twoim przykładzie nie widać protokołu - bez tego raczej się nie da...
Musisz zdefiniować jakiś protokół - czyli kiedy, co i kto wysyła, oraz jaka
jest odpowiedź na to, co odebrano od partnera - dotyczy to i klienta i serwera.
Obsługa błędów tez powinna być przewidziana w protokole.
Jeden klient = jeden wątek w serwerze.
Wątek w serwerze obsługujący klienta i wątek klienta powinny być na oko dość
symetryczne - odpowiadają za obsługę protokołu.
Żadnych sleep() w wątkach tego rodzaju! Synchronizacja nastąpi na strumieniach
utworzonych na gniazdku - jak serwer wywoła "read", to zatrzyma swoje działanie
do momentu, aż klient czegoś nie "write" i odwrotnie. Na tym polega protokół.
Kiedy, co i kto robi jakieś "write" i jaka będzie na to odpowiedź ("read")
- to jest właśnie protokół.
Na oko widać, że idziesz w kierunku protokołu tekstowego, więc używaj strumieni,
w których ogranicznikiem będzie \n - strumienie z metodami readLine i println
będą odpowiednie i zapewnią konieczną synchronizację.
> Wznowienie nastepuje ale ponownie wlaczony serwer po przerwie - otrzymuje kilkanascie prob rozpoczęcia polaczenia ze strony przedstawionego klienta. Jak czas niedostępności serwera jest zbyt dlugi - aplikacja kliencka niestety "pada":(
Kilkanaście prób, bo u Ciebie chyba robi się kilkanaście wątków, które próbują
"wznawiać" połączenie. Te pętle ze sleepami to genialne wylęgarnie hazardów :)
--
TrzyLinie
Re: Java i automatyczne wznawianie połączenia klienckiego socket
Author: Artik
Date: Tue, 11 Dec 2012 17:08
Date: Tue, 11 Dec 2012 17:08
20 lines
2371 bytes
2371 bytes
> W Twoim przykładzie nie widać protokołu - bez tego raczej się nie da... Aby nie komplikowac sprawy (synchroized dla socketow itp.) postanowilem odbior danych z serwera zrealizowac na drugim gniazdku. W ten sposob elementarnie rozwiazujac sprawę udalo mi się to jakos opanowac - tj. do momentu skargi uzytkownika. Stad jeden socket uzywam do wysylania inny do odbioru informacji poniewaz to co serwer wysyla do klienta nie zawsze jest zwiazane z synchroniczna wymiana danych (czasem - nie moge przewidziec, kiedy serwer chce cos powiedziec klientowi > Żadnych sleep() w wątkach tego rodzaju! Synchronizacja nastąpi na strumieniach > > utworzonych na gniazdku - jak serwer wywoła "read", to zatrzyma swoje działanie > > do momentu, aż klient czegoś nie "write" i odwrotnie. U mnie klient decyduje kiedy dane poleca do serwera - stad ten sleep jest tu ustawiony w przykladzie na sztywno a docelowo zmiennie w zaleznosci od sytuacji na kliencie Bardzo dziękuję za zainteresowanie i pomoc. Artik
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads