Serwer wielowątkowy

0

Witam, jestem początkujący w Javie, mam następujący problem:

Chciałbym zrobić prosty serwer wielowątkowy (bez żadnych rewelacji, odpowiada na żądania przeglądarki i wysyła pliki). Ustawiłem wysyłanie odpowiednich nagłówków wraz z zawartością w zależności od MIME type (żeby nie komplikować sprawy, pobieranego z rozszerzenia pliku).

Niestety jeśli do serwera spływa za dużo żądań na raz to niektóre okazują się puste; np. jeśli chcę wczytać stronę HTML na której osadziłem kilkanaście dużych obrazków, kilka z nich się nie wczytuje.

Pętla główna wygląda mniej więcej tak (pominąłem nieistotne linijki):

ServerSocket ss;
Socket polaczenie;
		
	ss = new ServerSocket(82);
	while(true){

				polaczenie = ss.accept();
				Thread  task = new Thread(new MySocketHandler( polaczenie, documentRoot )) ;
				task.start();
				
	}

a w metodzie run() MySocketHandlera jest

...
		byte[] bInputMsg = null;
		
		int len = polaczenie.getInputStream().available();
		bInputMsg = new byte[len];
		polaczenie.getInputStream().read(bInputMsg);

i czasami zdarza się że len == 0... W efekcie jeśli na stronie jest 15 obrazków to wczyta się np. tylko 10

Robię jakiś błąd ideowy? Próbowałem między połączeniami wywoływać sleep ale to nie poprawia sytuacji (może jak bym ustawił bardzo długiego, to by coś dało, ale to bez sensu, poza tym mój prowadzący laborkę coś kręci nosem na usypianie programu).

Pozdrawiam, z góry dzięki za wszystkie wskazówki.

0

Szkielet Executor. Pozwala na kolejkowanie wywołania wątków.
http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/Chapter10/concurrencyTools.html

0

Wczytywać ze strumienia należy w pętli aż read() zwróci -1 lub zostanie rzucony wyjątek.
Użyj metody read(), najlepiej tej, która przyjmuje jako argument tablicę.
Stosowanie w pętli available() prowadzi do aktywnego oczekiwania.

No i oczywiście użyj puli wątków.

Pamiętaj tylko o sprawdzaniu ścieżki, którą żąda użytkownik, bo może podać np. "../../tajny_folder/tajny_plik". Najbezpieczniej użyć metody getResource() klasy ClassLoader.

0

Sam Executor nic mi tu nie pomógł, druga porada nakierowała mnie na rozwiązanie;
zamiast

int len = polaczenie.getInputStream().available();

zrobiłem

int len = -1;
while(len <= 0) {
 len = polaczenie.getInputStream().available();
}

i potem już normalnie, read() całości.

Pozdrawiam i dzięki za pomoc.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.