2011-01-06 25 views
9

Próbuję utworzyć aplikację Java w sposób klient/serwer. Klient jest GUI w SWT, który wyświetla dane z serwera. Serwer jest podłączony do bazy danych.Utwórz aplikację java serwera klienta

Ok, przepraszam za to, jestem pewien, że to klasyczne pytanie, ale nie wiem jak zacząć.

W projekcie, w którym pracowałem, zaimplementowali mnóstwo magii, używając Proxy.newProxyInstance() do transparentnego wywoływania serwera Glassfish.

Nie chcę używać serwera Glassfish. Chcę po prostu czegoś prostego w zwykłej Javie. Ale koncepcja serwerów proxy wydaje się całkiem fajna.

Czy masz pomysły lub przykłady takich rzeczy? Jak napisać część serwera, aby obsłużyć żądania klientów?

góry dzięki

Fluminis

+0

Chciałbym zasugerować próbę rozwiązania JMS Producer/Consumer, ale chcesz czegoś prostego. –

Odpowiedz

34

Wyjaśnię TCP:
Podstawową koncepcją jest konieczność uruchomienia "Serwera" na komputerze. Ten serwer akceptuje klientów oczekujących na połączenie. Każde połączenie przechodzi przez port (mam nadzieję, że ...).
Zawsze używaj porty powyżej 1024, ponieważ porty są niższe niż w 1025 roku większość czasu zarezerwowanego dla standardowych protokołów (takich jak HTTP (80), (21) FTP, Telnet, ...)

Jednak stworzenie serwera w Javie w ten sposób:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on. 

"Socket" to słowo, którego prawdopodobnie szukasz, jeśli chcesz przeprowadzić badania.
I podłączyć klienta do serwera musisz napisać to:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port 

Ale teraz, nie ma jeszcze połączenia.Serwer musi zaakceptować klienta oczekującego (jak zauważyłem powyżej):

Socket connectionToTheClient = server.accept(); 

Zrobione! Twoje połączenie zostało ustanowione! Komunikacja jest podobna do File-IO. Jedyną rzeczą, o której musisz pamiętać, jest to, że musisz zdecydować, kiedy chcesz opróżnić bufor i naprawdę wysłać dane przez gniazdo.
Korzystanie z PrintStream dla tekstu pisanie jest bardzo poręczny:

OutputStream out = yourSocketHere.getOutputStream(); 
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true 
ps.println("Hello, Other side of the connection!"); 
// Now, you don't have to flush it, because of the auto-flush flag we turned on. 

BufferedReader dla tekstu czytaniu jest dobre (najlepiej *) opcja:

InputStream in = yourSocketHere.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
String line = br.readLine(); 
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection. 

Mam nadzieję, że można zacząć z sieci z tego Informacja!
PS: Oczywiście, cały kod sieciowy musi być sprawdzony pod kątem IOExceptions.

EDYCJA: Zapomniałem napisać, dlaczego nie zawsze jest to najlepsza opcja. BufferedReader używa bufora i czyta tyle, ile może w buforze. Ale czasami nie chcesz, żeby BufferedReader przechwytywał bajty po znaku nowej linii i wstawiał je do własnego bufora.
Krótki przykład:

InputStream in = socket.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
// The other side says hello: 
String text = br.readLine(); 
// For whatever reason, you want to read one single byte from the stream, 
// That single byte, just after the newline: 
byte b = (byte) in.read(); 

Ale BufferedReader już, że bajt, chcesz czytać w swoim buforze. Dlatego wywołanie in.read() zwróci bajt następujący po ostatnim bajcie w buforze czytnika.

Tak więc w tej sytuacji najlepszym rozwiązaniem jest użycie DataInputStream i zarządzanie nim w swój własny sposób, aby wiedzieć, jak długo łańcuch będzie i przeczytać tylko tę liczbę bajtów i przekształcić je w ciąg. Lub: Używasz:

DataInputStream.readLine()

Ta metoda nie używa bufora i czyta bajt po bajcie i sprawdza, czy istnieje nowa linia. Ta metoda nie kradnie bajtów z bazowego InputStream.


EDIT: Można rozwijać swój własny protokół, w którym można wystąpić o wywołanie metody z wykorzystaniem Java Reflexion. Na przykład:

String className = ...; 
String methodName = ...; 
Class[] methodParamTypes = ...; 
Object[] methodParams = ...; 
Class cl = Class.forName(className); 
Method me = cl.getDelcaredMethod(methodName, methodParamTypes); 
Object returnValue = me.invoke(this, methodParams); 

Gdy masz swój przedmiot możesz wysłać go do drugiej strony połączenia z serializacji: ObjectOuputStreams i ObjectInputStreams. Za pomocą tych dwóch klas można pisać i czytać obiekty za pośrednictwem strumienia.

Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable) 
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream()); 
oos.writeObject(oos); 
oos.reset(); // (***) 
// Don't close it! Otherwise the connection will be closed as well. 

A po drugiej stronie połączenia:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
Object object = ois.readObject(); // Read the object 
// Don't close it! 
// Then cast it to whatever you want. 

(***): Sprawdź my question celu uzyskania dalszych informacji o reset() i kiedy go używać.

+0

Dziękuję za odpowiedź. Rozumiem dobrze z Tobą przykład, jak pobierać tekst. Ale czy soket może wywołać metode na serwerze i uzyskać w zamian kompleksowy obiekt? – fluminis

+0

Zobacz ObjectOutputStream i ObjectInputStream. –

+1

również, możesz myśleć o java RMI (zdalna metoda wywoływania) - jest na nim dobra dokumentacja. –

3

Jeśli chcesz napisać prosty typu klient-serwer programu można postępować zgodnie z zaleceniami zawartymi w niniejszym tutorial.

Jeśli chcesz zrobić coś bardziej zaangażowanego, w zwykłej Javie, jak mówisz, być może trzeba będzie spojrzeć na RMI.

Jednak te dni, web services są wściekłości i może się okazać, że na dłuższą metę jest to prostsze.

1
  1. Zidentyfikować usługi, które chcesz przedstawić (loadThing, editThing, makeThingBelch)
  2. decydowania komunikacyjnego/protokołu komunikacyjnego (http wydaje straightfoward.)
  3. realizacji usług, testowanie jednostkowe często, aby upewnić się, że działa .
  4. TERAZ rozpocznij pisanie klienta, pamiętając, że możesz dodać nowe usługi lub zmienić istniejące.

Jedną z rzeczy, która przychodzi do głowy jest to, dlaczego chcesz napisać ją w "proste java", zamiast używać istniejącego serwera aplikacji? coś EJB3 do abstrakcji i zarządzania komunikacją, bezpieczeństwem, integralnością transakcyjną, itp.?

5

Glassfish może być bardziej skuteczny niż potrzeba, ale nie rezygnowałbym z wykorzystania istniejącej biblioteki.

Niektóre opcje gniazd:

Jeśli zdecydujesz się pójść bardziej w stronę usług internetowych niż gniazd, to Jetty jest sposobem na zastosowanie małego protokołu HTTP.

Powiązane problemy