Zerwane połączenie z serwerem

0

Załóżmy, że mamy klasę serwera:

public class Server {
	public static void main(String args[]) {
		ServerSocket connecting = null;
		Socket socket = null;
		try {
			connecting = new ServerSocket(8189);
			System.out.println("Server is on");
		}
		catch (Exception e) {
			System.out.println("Problem with server");
		}
		
		try {
			socket = connecting.accept();
			System.out.println("New user");
		}
		catch(Exception e) {
		}
		
		
		while (true) {
				if (socket.isClosed()) {
					System.out.println("Connecting is closed!");
				}
				else
				{
					System.out.println("Connecting is OK!");
				}
		}
	}
}

Nowy użytkownik łączy się z serwerem - jest OK - otrzymujemy wiadomość New User
Jednak jak zrealizować to, żeby w przypadku rozłączenia użytkownika server o tym się dowiedział?

W powyższym kodzie próbowałem sprawdzać socket.isClosed() ale ten sposób nie działa - nawet w przypadku, gdy zamknę aplikacje klienta, to z tym socketem nic się nie dzieje. Musiałbym pewnie jawnie użyć wcześniej socket.close(), ale to z kolei jest ciężkie bo okoliczności zerwania połączenia mogą być różne. Niekoniecznie musi być to zamknięcie aplikacji przez usera, ale np problemy z internetem.

Zresztą zrzucenie odpowiedzialności na aplikacje klienta chyba nie jest najlepszym wyborem, może to powodować różne problemy - to serwer powinien co jakiś czas sprawdzać, czy podłączony użytkownik jest ciągle aktywny... Pewnie jest za to odpowiedzialna jedna prosta metoda...

0

http://download.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#accept()
Łapanie wyjątków czasem jednak bywa przydatne :P Wrzuć obsługę zerwania połączenia do bloku 'catch'

try {
  socket = connecting.accept();
  System.out.println("New user");
}  catch(Exception e) {
} 
0

Zapomniałem dopisać, że obsługa połączenia powinna być oczywiście w bloku 'try'

0
eeee napisał(a)

http://download.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#accept()
Łapanie wyjątków czasem jednak bywa przydatne :P Wrzuć obsługę zerwania połączenia do bloku 'catch'

try {
socket = connecting.accept();
System.out.println("New user");
} catch(Exception e) {
}



Tylko właśnie o to jest pytanie, jak wykryć <i>zerwanie połączenia</i> ?

try {
socket = connecting.accept();
System.out.println("New user");
while(true) {
if (socket.isClose()) { //cos }
}
} catch(Exception e) {
}


bo z tym <i>isClose</i> nie bardzo działa ;)
0

dodaj do bloku exception 'e.printStackTrace()'

0

Niestety, ale to nie za działa. Nie wiem czy mnie dobrze rozumiesz - mamy nawiązane połączenie Klient-Server, które w pewnej chwili jest zrywane i chcemy natychmiast podjąć pewne działania po stronie Servera.

		try {
			socket = connecting.accept();
			System.out.println("New user");
		}
		catch(Exception e) {
                                  System.out.println("To nie dziala");
			e.printStackTrace();
		}

W momencie zrywania połączenia (np zamykamy aplikacje Klienta) nic sie nie dzieje po stronie servera - to zdarzenie nie jest wykrywane i niestety kod w bloku catch nie rozwiązuje problemu (wyjątek byłby wyrzucony wtedy, gdyby nie udało się nawiązać połączenia na samym początku a nam chodzi o sytuację, że połączenie jest zrywane w dalszej części np w czasie przetwarzania jakiegos dluzszego procesu)

0
InputStream in = socket.getInputStream();
try {
	while(true)
	{
		int readen = in.read(); // tutaj moze poleciec IOException
		if(readen==-1)
		   throw new IOException("End of stream"); // i tutaj
	}
} catch (IOException e)
{
	// cos sie pieprznelo
	e.printStackStrace();
   
	// co nie znaczy, ze jest zamkniety
	if(!socket.isClosed())
	{
		try { socket.close(); } catch (IOException e) { /* nie obchodzi nas to */ }
	}
}

pisane na szybko

0

orest, w swoim ostatnim przykladzie nie zablokowales nigdzie przeplywu sterowania, po prostu nawiazales polaczenie(metoda accept blokuje przeplyw tylko do chwili nawiazania polaczenia) i konczyles dzialanie metody/programu.

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